Skip to content

fix(feishu): use msg_type media for mp4 video (fixes #33674)#33720

Merged
Takhoffman merged 7 commits intoopenclaw:mainfrom
polooooo:fix/feishu-mp4-msg-type-33674
Mar 5, 2026
Merged

fix(feishu): use msg_type media for mp4 video (fixes #33674)#33720
Takhoffman merged 7 commits intoopenclaw:mainfrom
polooooo:fix/feishu-mp4-msg-type-33674

Conversation

@polooooo
Copy link
Copy Markdown
Contributor

@polooooo polooooo commented Mar 4, 2026

Fixes #33674

Background

When sending an MP4 video via the Feishu channel (message tool with action=send, media=path.mp4), the recipient sees a text link like 📎 /path/to/video.mp4 instead of a playable video. The Feishu API requires msg_type: "media" for video files (e.g. mp4) to render them as in-chat media; using msg_type: "file" causes the link-style display.

Previously, sendMediaFeishu in extensions/feishu/src/media.ts used only two message types: "audio" for opus and "file" for everything else (including video). That matched upload file_type (e.g. mp4) but did not match the required send msg_type for video.

Changes

  • extensions/feishu/src/media.ts

    • In sendFileFeishu, extended msgType to allow "media" and updated the JSDoc to describe audio / media (video) / file usage.
    • In sendMediaFeishu, set msgType to "media" when the file type is mp4 (covers .mp4, .mov, .avi via detectFileType), so that video is sent with msg_type: "media" and displays as playable in Feishu.
  • extensions/feishu/src/media.test.ts

    • Updated tests that send mp4 to expect msg_type: "media" instead of "file" (e.g. "uses msg_type=media for mp4 video", "uses msg_type=media when replying with mp4", and the reply_in_thread case with mp4).

Testing

  • pnpm exec vitest run extensions/feishu/src/media.test.ts — all 26 tests pass.
  • No new lint issues; existing Feishu media tests cover msg_type routing for opus, mp4, and documents.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 4, 2026

Greptile Summary

This PR fixes a bug where sending an MP4 video via the Feishu channel would display as a text link (📎 /path/to/video.mp4) instead of an inline playable video. The root cause was that sendMediaFeishu used msg_type: "file" for all non-audio uploads, but the Feishu API requires msg_type: "media" to render videos inline.

The fix is minimal and targeted:

  • Extends the msgType union type in sendFileFeishu to include "media" (line 332).
  • Updates the msgType selection logic in sendMediaFeishu from a two-way (opus"audio", else → "file") to a three-way branch (opus"audio", mp4"media", else → "file") (line 471).
  • Updates the three affected test expectations accordingly (lines 116–135, 179–196, 198–217).

Key observations:

  • sendFileFeishu is the only call site — no other callers are impacted.
  • The content payload ({ file_key: fileKey }) remains valid for msg_type: "media"; Feishu's API treats image_key (cover image) as optional for that message type.
  • Note that detectFileType maps .mov and .avi to the internal type "mp4", so those extensions will also be sent with msg_type: "media" after this change. Tests only cover .mp4 filenames directly, but detectFileType itself is responsible for that mapping and is covered elsewhere.

Confidence Score: 5/5

  • This PR is safe to merge — the change is minimal, well-tested, and correctly maps Feishu's API semantics for video messages.
  • The fix is a single-line ternary change with a corresponding TypeScript type update and properly updated tests. sendFileFeishu has only one call site, so there is no risk of regressions elsewhere. The content payload ({ file_key: fileKey }) is valid for all three msg_type values (file, audio, media). No new logic paths are introduced.
  • No files require special attention

Last reviewed commit: 7a46280

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bdfaa41f4c

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

polooooo and others added 5 commits March 4, 2026 20:18
Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.
@Takhoffman Takhoffman force-pushed the fix/feishu-mp4-msg-type-33674 branch from bdfaa41 to c58b576 Compare March 5, 2026 02:18
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d3623d2819

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@Takhoffman Takhoffman merged commit 68e68bf into openclaw:main Mar 5, 2026
28 checks passed
Kansodata pushed a commit to Kansodata/openclaw that referenced this pull request Mar 5, 2026
…penclaw#33720)

* fix(feishu): use msg_type media for mp4 video (fixes openclaw#33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
krakenhavoc added a commit to krakenhavoc/openclaw that referenced this pull request Mar 5, 2026
* fix(gateway): flush throttled delta before emitChatFinal (#24856)

* fix(gateway): flush throttled delta before emitChatFinal

The 150ms throttle in emitChatDelta can suppress the last text chunk
before emitChatFinal fires, causing streaming clients (e.g. ACP) to
receive truncated responses. The final event carries the complete text,
but clients that build responses incrementally from deltas miss the
tail end.

Flush one last unthrottled delta with the complete buffered text
immediately before sending the final event. This ensures all streaming
consumers have the full response without needing to reconcile deltas
against the final payload.

* fix(gateway): avoid duplicate delta flush when buffer unchanged

Track the text length at the time of the last broadcast. The flush in
emitChatFinal now only sends a delta if the buffer has grown since the
last broadcast, preventing duplicate sends when the final delta passed
the 150ms throttle and was already broadcast.

* fix(gateway): honor heartbeat suppression in final delta flush

* test(gateway): add final delta flush and dedupe coverage

* fix(gateway): skip final flush for silent lead fragments

* docs(changelog): note gateway final-delta flush fix credits

---------

Co-authored-by: Jonathan Taylor <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>

* fix: repair Feishu reset hook typing and stabilize secret resolver timeout

* chore(release): bump to 2026.3.3 and seed changelog

* ci: enable stale workflow

* fix: scope extension runtime deps to plugin manifests

* docs(changelog): reattribute duplicated PR credits

* fix(gateway+acp): thread stopReason through final event to ACP bridge (#24867)

Complete the stop reason propagation chain so ACP clients can
distinguish end_turn from max_tokens:

- server-chat.ts: emitChatFinal accepts optional stopReason param,
  includes it in the final payload, reads it from lifecycle event data
- translator.ts: read stopReason from the final payload instead of
  hardcoding end_turn

Chain: LLM API → run.ts (meta.stopReason) → agent.ts (lifecycle event)
→ server-chat.ts (final payload) → ACP translator (PromptResponse)

* fix(line): synthesize media/auth/routing webhook regressions (openclaw#32546) thanks @Takhoffman

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(test): stabilize appcast version assertion

* fix(ci): handle disabled systemd units in docker doctor flow

* test(live): harden gateway model profile probes

* fix(telegram): debounce forwarded media-only bursts

* test(e2e): isolate module mocks across harnesses

* security(line): synthesize strict LINE auth boundary hardening

LINE auth boundary hardening synthesis for inbound webhook authn/z/authz:
- account-scoped pairing-store access
- strict DM/group allowlist boundary separation
- fail-closed webhook auth/runtime behavior
- replay and duplicate handling with in-flight continuity for concurrent redeliveries

Source PRs: #26701, #26683, #25978, #17593, #16619, #31990, #26047, #30584, #18777
Related continuity context: #21955

Co-authored-by: bmendonca3 <[email protected]>
Co-authored-by: davidahmann <[email protected]>
Co-authored-by: harshang03 <[email protected]>
Co-authored-by: haosenwang1018 <[email protected]>
Co-authored-by: liuxiaopai-ai <[email protected]>
Co-authored-by: coygeek <[email protected]>
Co-authored-by: lailoo <[email protected]>

* chore: Updated Brave documentation (#26860)

Merged via squash.

Prepared head SHA: f8fc4bf01e0eacfb01f6ee58eea445680f7eeebd
Co-authored-by: HenryLoenwind <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix: improve compaction summary instructions to preserve active work (#8903)

fix: improve compaction summary instructions to preserve active work

Expand staged-summary merge instructions to preserve active task status, batch progress, latest user request, and follow-up commitments so compaction handoffs retain in-flight work context.

Co-authored-by: joetomasone <[email protected]>
Co-authored-by: Josh Lehman <[email protected]>

* bug: Workaround for QMD upstream bug (#27028)

Merged via squash.

Prepared head SHA: 939f9f4574fcfe08762407ab9e8d6c85a77a0899
Co-authored-by: HenryLoenwind <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* Diffs: Migrate tool usage guidance from before_prompt_build to a plugin skill (#32630)

Merged via squash.

Prepared head SHA: 585697a4e1556baa2cd79a7b449b120c4fd87e17
Co-authored-by: sircrumpet <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* feat(mattermost): add native slash command support (refresh) (#32467)

Merged via squash.

Prepared head SHA: 989126574ead75c0eedc185293659eb0d4fc6844
Co-authored-by: mukhtharcm <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* Gateway: fix stale self version in status output (#32655)

Merged via squash.

Prepared head SHA: b9675d1f90ef0eabb7e68c24a72d4b2fb27def22
Co-authored-by: liuxiaopai-ai <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* agents: propagate config for embedded skill loading

* fix(telegram): warn when accounts.default is missing in multi-account setup (#32544)

Merged via squash.

Prepared head SHA: 7ebc3f65b21729137d352fa76bc31f2f849934c0
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* macOS: add tailscale serve discovery fallback for remote gateways (#32860)

* feat(macos): add tailscale serve gateway discovery fallback

* fix: add changelog note for tailscale serve discovery fallback (#32860) (thanks @ngutman)

* fix(telegram): run outbound message hooks in reply delivery path

* fix(telegram): mark message_sent success only when delivery occurred

* fix(telegram): include reply hook metadata

* docs: update changelog for telegram message_sent fix (#32649)

* fix: guard malformed Telegram replies and pass hook accountId

* fix(heartbeat): scope exec wake dispatch to session key (#32724)

Merged via squash.

Prepared head SHA: 563fee0e65af07575f3df540cab2e1e5d5589f06
Co-authored-by: altaywtf <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* fix(telegram): prevent duplicate messages in DM draft streaming mode (#32118)

* fix(telegram): prevent duplicate messages in DM draft streaming mode

When using sendMessageDraft for DM streaming (streaming: 'partial'),
the draft bubble auto-converts to the final message. The code was
incorrectly falling through to sendPayload() after the draft was
finalized, causing a duplicate message.

This fix checks if we're in draft preview mode with hasStreamedMessage
and skips the sendPayload call, returning "preview-finalized" directly.

Key changes:
- Use hasStreamedMessage flag instead of previewRevision comparison
- Avoids double stopDraftLane calls by returning early
- Prevents duplicate messages when final text equals last streamed text

Root cause: In lane-delivery.ts, the final message handling logic
did not properly handle the DM draft flow where sendMessageDraft
creates a transient bubble that doesn't need a separate final send.

* fix(telegram): harden DM draft finalization path

* fix(telegram): require emitted draft preview for unchanged finals

* fix(telegram): require final draft text emission before finalize

* fix: update changelog for telegram draft finalization (#32118) (thanks @OpenCils)

---------

Co-authored-by: Ayaan Zaidi <[email protected]>

* fix: substitute YYYY-MM-DD at session startup and post-compaction (#32363) (#32381)

Merged via squash.

Prepared head SHA: aee998a2c1a911d3fef771aa891ac315a2f7dc53
Co-authored-by: chengzhichao-xydt <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* chore: note about pagination

* Compaction/Safeguard: preserve recent turns verbatim (#25554)

Merged via squash.

Prepared head SHA: 7fb33c411c4aaea2795e490fcd0e647cf7ea6fb8
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix: ignore discord wildcard audit keys (#33125) (thanks @thewilloftheshadow) (#33125)

* fix: Discord acp inline actions + bound-thread filter (#33136) (thanks @thewilloftheshadow) (#33136)

* fix: harden Discord channel resolution (#33142) (thanks @thewilloftheshadow) (#33142)

* docs(loop-detection): fix config keys to match schema (#33182)

Merged via squash.

Prepared head SHA: 612ecc00d36cbbefb0657f0a2ac0898d53a5ed73
Co-authored-by: Mylszd <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* feat(tool-truncation): use head+tail strategy to preserve errors during truncation (#20076)

Merged via squash.

Prepared head SHA: 6edebf22b1666807b1ea5cba5afb614c41dc3dd1
Co-authored-by: jlwestsr <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* iOS Security Stack 1/5: Keychain Migrations + Tests (#33029)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: da2f8f614155989345d0d3efd0c0f29ef410c187
Co-authored-by: mbelinky <[email protected]>
Co-authored-by: mbelinky <[email protected]>
Reviewed-by: @mbelinky

* fix: improve discord chunk delivery (#33226) (thanks @thewilloftheshadow) (#33226)

* fix(discord): default presence online when unconfigured

* fix(discord): stop typing after silent runs

* fix(discord): use fetch for voice upload slots

* test(discord): align bound-thread target kind

* iOS Security Stack 2/5: Concurrency Locks (#33241)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: b99ad804fbcc20bfb3042ac1da9050a7175f009c
Co-authored-by: mbelinky <[email protected]>
Co-authored-by: mbelinky <[email protected]>
Reviewed-by: @mbelinky

* iOS Security Stack 3/5: Runtime Security Guards (#33031)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 99171654014d1960edcaca8312ef6a47d3c08399
Co-authored-by: mbelinky <[email protected]>
Co-authored-by: mbelinky <[email protected]>
Reviewed-by: @mbelinky

* fix: discord mention handling (#33224) (thanks @thewilloftheshadow) (#33224)

* iOS Security Stack 4/5: TTS PCM->MP3 Fallback (#30885) (#33032)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: f77e3d764425a23ab5d5b55593d9e14622f1ef95
Co-authored-by: mbelinky <[email protected]>
Co-authored-by: mbelinky <[email protected]>
Reviewed-by: @mbelinky

* fix: allowlist Discord CDN hostnames for SSRF media (#33275) (thanks @thewilloftheshadow) (#33275)

* fix: stabilize Telegram draft boundaries and suppress NO_REPLY lead leaks (#33169)

* fix: stabilize telegram draft stream message boundaries

* fix: suppress NO_REPLY lead-fragment leaks

* fix: keep underscore guard for non-NO_REPLY prefixes

* fix: skip assistant-start rotation only after real lane rotation

* fix: preserve finalized state when pre-rotation does not force

* fix: reset finalized preview state on message-start boundary

* fix: document Telegram draft boundary + NO_REPLY reliability updates (#33169) (thanks @obviyus)

* fix: discord auto presence health signal (#33277) (thanks @thewilloftheshadow) (#33277)

* docs: document discord ignoreOtherMentions

* fix(discord): skip bot messages before debounce

* fix(discord): honor agent media roots in replies

* fix(discord): harden slash command routing

* fix(discord): reset thread sessions on archive

* fix: drop discord opus dependency

* feat(discord): add allowBots mention gating

* fix(docs): use MDX-safe secretref markers

* fix(docs): avoid MDX regex markers in secretref page

* docs(security): document Docker UFW hardening via DOCKER-USER (#27613)

Merged via squash.

Prepared head SHA: 31ddd433265d8a7efbf932c941678598bf6be30c
Co-authored-by: dorukardahan <[email protected]>
Co-authored-by: grp06 <[email protected]>
Reviewed-by: @grp06

* docs(contributing): require before/after screenshots for UI PRs (#32206)

Merged via squash.

Prepared head SHA: d7f0914873aec1c3c64c9161771ff0bcbc457c95
Co-authored-by: hydro13 <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* fix(discord): align DiscordAccountConfig.token type with SecretInput (#32490)

Merged via squash.

Prepared head SHA: 233aa032f1d894b7eb6a960247baa1336f8fbc26
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: joshavant <[email protected]>
Reviewed-by: @joshavant

* docs: fix secretref marker rendering in credential surface

* fix: harden pr review artifact validation

* fix(gateway): include disk-scanned agent IDs in listConfiguredAgentIds (#32831)

Merged via squash.

Prepared head SHA: 2aa58f6afd6e7766119575648483de6b5f50da6f
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* Agent: unify bootstrap truncation warning handling (#32769)

Merged via squash.

Prepared head SHA: 5d6d4ddfa620011e267d892b402751847d5ac0c3
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(logging ): use local timezone for console log timestamps (#25970)

Merged via squash.

Prepared head SHA: 30123265b7b910b9208e8c9407c30536e46eb68f
Co-authored-by: openperf <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* security: add X-Content-Type-Options nosniff header to media route (#30356)

Merged via squash.

Prepared head SHA: b14f9ad7ca7017c6e31fb18c8032a81f49686ea4
Co-authored-by: 13otKmdr <[email protected]>
Co-authored-by: grp06 <[email protected]>
Reviewed-by: @grp06

* fix(ios): guard talk TTS callbacks to active utterance (#33304)

Merged via squash.

Prepared head SHA: dd88886e416e5e6d6c08bf92162a5ff18c1eb229
Co-authored-by: mbelinky <[email protected]>
Co-authored-by: mbelinky <[email protected]>
Reviewed-by: @mbelinky

* fix(ios): start incremental speech at soft boundaries (#33305)

Merged via squash.

Prepared head SHA: d1acf723176f8e9d89f8c229610c9400ab661ec7
Co-authored-by: mbelinky <[email protected]>
Co-authored-by: mbelinky <[email protected]>
Reviewed-by: @mbelinky

* Telegram/device-pair: auto-arm one-shot notify on /pair qr with manual fallback (#33299)

Merged via squash.

Prepared head SHA: 0986691fd4d2f37dd2de7ac601b1e5480602c829
Co-authored-by: mbelinky <[email protected]>
Co-authored-by: mbelinky <[email protected]>
Reviewed-by: @mbelinky

* fix(ios): harden watch messaging activation concurrency (#33306)

Merged via squash.

Prepared head SHA: d40f8c4afbd6ddf38548c9b0c6ac6ac4359f2e54
Co-authored-by: mbelinky <[email protected]>
Co-authored-by: mbelinky <[email protected]>
Reviewed-by: @mbelinky

* docs: fix Mintlify-incompatible links in security docs (#27698)

Merged via squash.

Prepared head SHA: 6078cd94ba38b49d17e9680073337885c5f9e781
Co-authored-by: clawdoo <[email protected]>
Co-authored-by: grp06 <[email protected]>
Reviewed-by: @grp06

* fix(security): strip partial API token from status labels (#33262)

Merged via squash.

Prepared head SHA: 5fe81704e678dc5b18ca9416e5eb0750cfe49fb6
Co-authored-by: cu1ch3n <[email protected]>
Co-authored-by: grp06 <[email protected]>
Reviewed-by: @grp06

* Security audit: suggest valid gateway.nodes.denyCommands entries (#29713)

Merged via squash.

Prepared head SHA: db23298f9806b8de8c4b3e816f1649c18ebc0c64
Co-authored-by: liquidhorizon88-bot <[email protected]>
Co-authored-by: grp06 <[email protected]>
Reviewed-by: @grp06

* Agents: preserve bootstrap warning dedupe across followup runs

* feat(gateway): add Permissions-Policy header to default security headers (#30186)

Merged via squash.

Prepared head SHA: 0dac89283f54840ec2244007ff5a6178ce8b2ba9
Co-authored-by: habakan <[email protected]>
Co-authored-by: grp06 <[email protected]>
Reviewed-by: @grp06

* fix(plugins): lazily initialize runtime and split plugin-sdk startup imports (#28620)

Merged via squash.

Prepared head SHA: 8bd7d6c13b070f86bd4d5c45286c1ceb1a3f9f80
Co-authored-by: hmemcpy <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* build: fix ineffective dynamic imports with lazy boundaries (#33690)

Merged via squash.

Prepared head SHA: 38b3c23d6f8f2b4c8a36a88ee65b508102f1ec36
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(feishu): support SecretRef-style env credentials in account resolver (#30903)

Merged via squash.

Prepared head SHA: d3d0a18f173e999070dae4ff01423dadd2804a9c
Co-authored-by: LiaoyuanNing <[email protected]>
Co-authored-by: joshavant <[email protected]>
Reviewed-by: @joshavant

* fix(config): detect top-level heartbeat as invalid config path (#30894) (#32706)

Merged via squash.

Prepared head SHA: 1714ffe6fc1e3ed6a8a120d01d074f1be83c62d3
Co-authored-by: xiwan <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* Config: harden legacy heartbeat key migration

* build: prevent mixed static/dynamic pi-model-discovery imports

* follow-up: align ingress, atomic paths, and channel tests with credential semantics (#33733)

Merged via squash.

Prepared head SHA: c290c2ab6a3c3309adcbc4dc834f3c10d2ae1039
Co-authored-by: joshavant <[email protected]>
Co-authored-by: joshavant <[email protected]>
Reviewed-by: @joshavant

* plugin-sdk: add channel subpaths and migrate bundled plugins

* fix(tlon): use HTTPS git URL for api-beta

* fix: stabilize telegram draft boundary previews (#33842) (thanks @ngutman)

* Runtime: stabilize tool/run state transitions under compaction and backpressure

Synthesize runtime state transition fixes for compaction tool-use integrity and long-running handler backpressure.

Sources: #33630, #33583

Co-authored-by: Kevin Shenghui <[email protected]>
Co-authored-by: Theo Tarr <[email protected]>

* fix(extensions): synthesize mediaLocalRoots propagation across sendMedia adapters

Restore deterministic mediaLocalRoots propagation through extension sendMedia adapters and add coverage for local/remote media handling in Google Chat.

Synthesis of #33581, #33545, #33540, #33536, #33528.

Co-authored-by: bmendonca3 <[email protected]>

* fix(gateway): synthesize lifecycle robustness for restart and startup probes (#33831)

* fix(gateway): correct launchctl command sequence for gateway restart (closes #20030)

* fix(restart): expand HOME and escape label in launchctl plist path

* fix(restart): poll port free after SIGKILL to prevent EADDRINUSE restart loop

When cleanStaleGatewayProcessesSync() kills a stale gateway process,
the kernel may not immediately release the TCP port. Previously the
function returned after a fixed 500ms sleep (300ms SIGTERM + 200ms
SIGKILL), allowing triggerOpenClawRestart() to hand off to systemd
before the port was actually free. The new systemd process then raced
the dying socket for port 18789, hit EADDRINUSE, and exited with
status 1, causing systemd to retry indefinitely — the zombie restart
loop reported in #33103.

Fix: add waitForPortFreeSync() that polls lsof at 50ms intervals for
up to 2 seconds after SIGKILL. cleanStaleGatewayProcessesSync() now
blocks until the port is confirmed free (or the budget expires with a
warning) before returning. The increased SIGTERM/SIGKILL wait budgets
(600ms / 400ms) also give slow processes more time to exit cleanly.

Fixes #33103
Related: #28134

* fix: add EADDRINUSE retry and TIME_WAIT port-bind checks for gateway startup

* fix(ports): treat EADDRNOTAVAIL as non-retryable and fix flaky test

* fix(gateway): hot-reload agents.defaults.models allowlist changes

The reload plan had a rule for `agents.defaults.model` (singular) but
not `agents.defaults.models` (plural — the allowlist array).  Because
`agents.defaults.models` does not prefix-match `agents.defaults.model.`,
it fell through to the catch-all `agents` tail rule (kind=none), so
allowlist edits in openclaw.json were silently ignored at runtime.

Add a dedicated reload rule so changes to the models allowlist trigger
a heartbeat restart, which re-reads the config and serves the updated
list to clients.

Fixes #33600

Co-authored-by: HCL <[email protected]>
Signed-off-by: HCL <[email protected]>

* test(restart): 100% branch coverage — audit round 2

Audit findings fixed:
- remove dead guard: terminateStaleProcessesSync pids.length===0 check was
  unreachable (only caller cleanStaleGatewayProcessesSync already guards)
- expose __testing.callSleepSyncRaw so sleepSync's real Atomics.wait path
  can be unit-tested directly without going through the override
- fix broken sleepSync Atomics.wait test: previous test set override=null
  but cleanStaleGatewayProcessesSync returned before calling sleepSync —
  replaced with direct callSleepSyncRaw calls that actually exercise L36/L42-47
- fix pid collision: two tests used process.pid+304 (EPERM + dead-at-SIGTERM);
  EPERM test changed to process.pid+305
- fix misindented tests: 'deduplicates pids' and 'lsof status 1 container
  edge case' were outside their intended describe blocks; moved to correct
  scopes (findGatewayPidsOnPortSync and pollPortOnce respectively)
- add missing branch tests:
  - status 1 + non-empty stdout with zero openclaw pids → free:true (L145)
  - mid-loop non-openclaw cmd in &&-chain (L67)
  - consecutive p-lines without c-line between them (L67)
  - invalid PID in p-line (p0 / pNaN) — ternary false branch (L67)
  - unknown lsof output line (else-if false branch L69)

Coverage: 100% stmts / 100% branch / 100% funcs / 100% lines (36 tests)

* test(restart): fix stale-pid test typing for tsgo

* fix(gateway): address lifecycle review findings

* test(update): make restart-helper path assertions windows-safe

---------

Signed-off-by: HCL <[email protected]>
Co-authored-by: Glucksberg <[email protected]>
Co-authored-by: Efe Büken <[email protected]>
Co-authored-by: Riccardo Marino <[email protected]>
Co-authored-by: HCL <[email protected]>

* fix(routing): unify session delivery invariants for duplicate suppression (#33786)

* Routing: unify session delivery invariants

* Routing: address PR review feedback

* Routing: tighten topic and session-scope suppression

* fix(chat): inherit routes for per-account channel-peer sessions

* feat(telegram): add per-topic agent routing for forum groups [AI-assisted]

This feature allows different topics within a Telegram forum supergroup to route
to different agents, each with isolated workspace, memory, and sessions.

Key changes:
- Add agentId field to TelegramTopicConfig type for per-topic routing
- Add zod validation for agentId in topic config schema
- Implement routing logic to re-derive session key with topic's agent
- Add debug logging for topic agent overrides
- Add unit tests for routing behavior (forum topics + DM topics)
- Add config validation tests
- Document feature in docs/channels/telegram.md

This builds on the approach from PR #31513 by @Sid-Qin with additional fixes
for security (preserved account fail-closed guard) and test coverage.

Closes #31473

* fix(telegram): address PR review comments

- Export pickFirstExistingAgentId and use it to validate topic agentId
- Properly update mainSessionKey when overriding route agent
- Fix docs example showing incorrect session key for topic 3

Fixes issue where non-existent agentId would create orphaned sessions.
Fixes issue where DM topic replies would route to wrong agent.

* fix: tighten telegram topic-agent docs + fallback tests (#33647) (thanks @kesor)

* fix(gateway): preserve route inheritance for legacy channel session keys (openclaw#33919) thanks @Takhoffman

Verified:
- pnpm build
- pnpm check
- pnpm test src/gateway/server-methods/chat.directive-tags.test.ts
- pnpm test:macmini

Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(sessions-spawn): remove maxLength from attachment content schema to fix llama.cpp GBNF grammar overflow

* fix: harden sessions_spawn attachment schema landing (#33648) (thanks @anisoptera)

* Deps: fix pnpm audit vulnerabilities in Google extension path (#33939)

* extensions/googlechat: require openclaw 2026.3.2+

* extensions/memory-core: require openclaw 2026.3.2+

* deps: bump fast-xml-parser override to 5.3.8

* deps: refresh lockfile for audit vulnerability fixes

* fix(gateway): narrow legacy route inheritance for custom session keys (openclaw#33932) thanks @Takhoffman

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* docs(changelog): credit #31513 in #33647 entry

* feat(web-search): switch Perplexity to native Search API (#33822)

* feat: Add Perplexity Search API as web_search provider

* docs fixes

* domain_filter validation

* address comments

* provider-specific options in cache key

* add validation for unsupported date filters

* legacy fields

* unsupported_language guard

* cache key matches the request's precedence order

* conflicting_time_filters guard

* unsupported_country guard

* invalid_date_range guard

* pplx validate for ISO 639-1 format

* docs: add Perplexity Search API changelog entry

* unsupported_domain_filter guard

---------

Co-authored-by: Shadow <[email protected]>

* feat(slack): add typingReaction config for DM typing indicator fallback (#19816)

* feat(slack): add typingReaction config for DM typing indicator fallback

Adds a reaction-based typing indicator for Slack DMs that works without
assistant mode. When `channels.slack.typingReaction` is set (e.g.
"hourglass_flowing_sand"), the emoji is added to the user's message when
processing starts and removed when the reply is sent.

Addresses #19809

* test(slack): add typingReaction to createSlackMonitorContext test callers

* test(slack): add typingReaction to test context callers

* test(slack): add typingReaction to context fixture

* docs(changelog): credit Slack typingReaction feature

* test(slack): align existing-thread history expectation

---------

Co-authored-by: Vincent Koc <[email protected]>

* plugins: avoid peer auto-install dependency bloat (#34017)

* plugins/install: omit peer deps during plugin npm install

* tests: assert plugin install omits peer deps

* extensions/googlechat: mark openclaw peer optional

* extensions/memory-core: mark openclaw peer optional

* fix: code/cli acpx reliability 20260304 (#34020)

* agents: switch claude-cli defaults to bypassPermissions

* agents: add claude-cli default args coverage

* agents: emit watchdog stall system event for cli runs

* agents: test cli watchdog stall system event

* acpx: fallback to sessions new when ensure returns no ids

* acpx tests: mock sessions new fallback path

* acpx tests: cover ensure-empty fallback flow

* skills: clarify claude print mode without pty

* docs: update cli-backends claude default args

* docs: refresh cli live test default args

* gateway tests: align live claude args defaults

* changelog: credit claude/acpx reliability fixes

* Agents: normalize legacy Claude permission flag overrides

* Tests: cover legacy Claude permission override normalization

* Changelog: note legacy Claude permission flag auto-normalization

* ACPX: fail fast when ensure/new return no session IDs

* ACPX tests: support empty sessions new fixture output

* ACPX tests: assert ensureSession failure when IDs missing

* CLI runner: scope watchdog heartbeat wake to session

* CLI runner tests: assert session-scoped watchdog wake

* Update CHANGELOG.md

* fix(outbound): unify resolved cfg threading across send paths (#33987)

* Plugins: add root-alias shim and cache/docs updates

* Extensions: migrate bluebubbles plugin-sdk imports

* Extensions: migrate device-pair plugin-sdk imports

* Extensions: migrate diagnostics-otel plugin-sdk imports

* Extensions: migrate diffs plugin-sdk imports

* Extensions: migrate feishu plugin-sdk imports

* Extensions: migrate google-gemini-cli-auth plugin-sdk imports

* Extensions: migrate googlechat plugin-sdk imports

* Extensions: migrate irc plugin-sdk imports

* Extensions: migrate llm-task plugin-sdk imports

* Extensions: migrate lobster plugin-sdk imports

* Extensions: migrate matrix plugin-sdk imports

* Extensions: migrate mattermost plugin-sdk imports

* Extensions: migrate minimax-portal-auth plugin-sdk imports

* Extensions: migrate msteams plugin-sdk imports

* Extensions: migrate nextcloud-talk plugin-sdk imports

* Extensions: migrate nostr plugin-sdk imports

* Extensions: migrate qwen-portal-auth plugin-sdk imports

* Extensions: migrate synology-chat plugin-sdk imports

* Extensions: migrate telegram plugin-sdk imports

* Extensions: migrate test-utils plugin-sdk imports

* Extensions: migrate tlon plugin-sdk imports

* Extensions: migrate twitch plugin-sdk imports

* Extensions: migrate voice-call plugin-sdk imports

* Extensions: migrate zalo plugin-sdk imports

* Extensions: migrate zalouser plugin-sdk imports

* Extensions: migrate acpx plugin-sdk imports

* fix(tui): normalize session key to lowercase to match gateway canonicalization (#34013)

Merged via squash.

Prepared head SHA: cfe06ca131661d1fd669270345c549ee8141cc46
Co-authored-by: lynnzc <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* Plugin SDK: add full bundled subpath wiring

* Plugins/acpx: migrate to scoped plugin-sdk imports

* Plugins/bluebubbles: migrate to scoped plugin-sdk imports

* Plugins/copilot-proxy: migrate to scoped plugin-sdk imports

* Plugins/device-pair: migrate to scoped plugin-sdk imports

* Plugins/diagnostics-otel: migrate to scoped plugin-sdk imports

* Plugins/diffs: migrate to scoped plugin-sdk imports

* Plugins/feishu: migrate to scoped plugin-sdk imports

* Plugins/google-gemini-cli-auth: migrate to scoped plugin-sdk imports

* Plugins/googlechat: migrate to scoped plugin-sdk imports

* Plugins/irc: migrate to scoped plugin-sdk imports

* Plugins/llm-task: migrate to scoped plugin-sdk imports

* Plugins/lobster: migrate to scoped plugin-sdk imports

* Plugins/matrix: migrate to scoped plugin-sdk imports

* Plugins/mattermost: migrate to scoped plugin-sdk imports

* Plugins/memory-core: migrate to scoped plugin-sdk imports

* Plugins/memory-lancedb: migrate to scoped plugin-sdk imports

* Plugins/minimax-portal-auth: migrate to scoped plugin-sdk imports

* Plugins/msteams: migrate to scoped plugin-sdk imports

* Plugins/nextcloud-talk: migrate to scoped plugin-sdk imports

* Plugins/nostr: migrate to scoped plugin-sdk imports

* Plugins/open-prose: migrate to scoped plugin-sdk imports

* Plugins/phone-control: migrate to scoped plugin-sdk imports

* Plugins/qwen-portal-auth: migrate to scoped plugin-sdk imports

* Plugins/synology-chat: migrate to scoped plugin-sdk imports

* Plugins/talk-voice: migrate to scoped plugin-sdk imports

* Plugins/test-utils: migrate to scoped plugin-sdk imports

* Plugins/thread-ownership: migrate to scoped plugin-sdk imports

* Plugins/tlon: migrate to scoped plugin-sdk imports

* Plugins/twitch: migrate to scoped plugin-sdk imports

* Plugins/voice-call: migrate to scoped plugin-sdk imports

* Plugins/whatsapp: migrate to scoped plugin-sdk imports

* Plugins/zalo: migrate to scoped plugin-sdk imports

* Plugins/zalouser: migrate to scoped plugin-sdk imports

* Chore: remove accidental .DS_Store artifact

* chore(docs): add plugins refactor changelog entry

* feat(ios): add Live Activity connection status + stale cleanup (#33591)

* feat(ios): add live activity connection status and cleanup

Add lock-screen/Dynamic Island connection health states and prune duplicate/stale activities before reuse. This intentionally excludes AI/title generation and heavier UX rewrites from #27488.

Co-authored-by: leepokai <[email protected]>

* fix(ios): treat ended live activities as inactive

* chore(changelog): add PR reference and author thanks

---------

Co-authored-by: leepokai <[email protected]>

* fix: kill stuck ACP child processes on startup and harden sessions in discord threads (#33699)

* Gateway: resolve agent.wait for chat.send runs

* Discord: harden ACP thread binding + listener timeout

* ACPX: handle already-exited child wait

* Gateway/Discord: address PR review findings

* Discord: keep ACP error-state thread bindings on startup

* gateway: make agent.wait dedupe bridge event-driven

* discord: harden ACP probe classification and cap startup fan-out

* discord: add cooperative timeout cancellation

* discord: fix startup probe concurrency helper typing

* plugin-sdk: avoid Windows root-alias shard timeout

* plugin-sdk: keep root alias reflection path non-blocking

* discord+gateway: resolve remaining PR review findings

* gateway+discord: fix codex review regressions

* Discord/Gateway: address Codex review findings

* Gateway: keep agent.wait lifecycle active with shared run IDs

* Discord: clean up status reactions on aborted runs

* fix: add changelog note for ACP/Discord startup hardening (#33699) (thanks @dutifulbob)

---------

Co-authored-by: Onur <[email protected]>

* fix: relay ACP sessions_spawn parent streaming (#34310) (thanks @vincentkoc) (#34310)

Co-authored-by: Onur Solmaz <[email protected]>

* fix(telegram): materialize dm draft final to avoid duplicates

* docs(changelog): credit @Brotherinlaw-13 for #34318

* fix: prevent nodes media base64 context bloat (#34332)

* fix: preserve raw media invoke for HTTP tool clients (#34365)

* fix(slack): route system events to bound agent sessions (#34045)

* fix(slack): route system events via binding-aware session keys

* fix(slack): pass sender to system event session resolver

* fix(slack): include sender context for interaction session routing

* fix(slack): include modal submitter in session routing

* test(slack): cover binding-aware system event routing

* test(slack): update interaction session key assertions

* test(slack): assert reaction session routing carries sender

* docs(changelog): note slack system event routing fix

* Update CHANGELOG.md

* Delete changelog/fragments directory

* fix(memory): serialize local embedding initialization to avoid duplicate model loads (#15639)

Merged via squash.

Prepared head SHA: a085fc21a8ba7163fffdb5de640dd4dc1ff5a88e
Co-authored-by: SubtleSpark <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(model): propagate custom provider headers to model objects (#27490)

Merged via squash.

Prepared head SHA: e4183b398fc7eb4c18b2b691cb0dd882ec993608
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(daemon): handle systemctl is-enabled exit 4 (not-found) on Ubuntu (#33634)

Merged via squash.

Prepared head SHA: 67dffc3ee239cd7b813cb200c3dd5475d9e203a6
Co-authored-by: Yuandiaodiaodiao <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(node-host): sync rawCommand with hardened argv after executable path pinning (#33137)

Merged via squash.

Prepared head SHA: a7987905f7ad6cf5fee286ffa81ceaad8297174f
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* Agents: add generic poll-vote action support

* fix(ollama): pass provider headers to Ollama stream function (#24285)

createOllamaStreamFn() only accepted baseUrl, ignoring custom headers
configured in models.providers.<provider>.headers. This caused 403
errors when Ollama endpoints are behind reverse proxies that require
auth headers (e.g. X-OLLAMA-KEY via HAProxy).

Add optional defaultHeaders parameter to createOllamaStreamFn() and
merge them into every fetch request. Provider headers from config are
now passed through at the call site in the embedded runner.

Fixes #24285

* test(ollama): add default header precedence coverage

* chore(changelog): add PR entry openclaw#24337 thanks @echoVic

* Outbound: allow text-only plugin adapters

* Outbound: avoid empty multi-media fallback sends

* chore(changelog): align outbound adapter entry openclaw#32788 thanks @liuxiaopai-ai

* fix(outbound): fail media-only text-only adapter fallback

* chore(changelog): clarify outbound media-only fallback openclaw#32788 thanks @liuxiaopai-ai

* fix(review): enforce behavioral sweep validation

* Fix gateway restart false timeouts on Debian/systemd (#34874)

* daemon(systemd): target sudo caller user scope

* test(systemd): cover sudo user scope commands

* infra(ports): fall back to ss when lsof missing

* test(ports): verify ss fallback listener detection

* cli(gateway): use probe fallback for restart health

* test(gateway): cover restart-health probe fallback

* Compaction/Safeguard: require structured summary headings (#25555)

Merged via squash.

Prepared head SHA: 0b1df34806a7b788261290be55760fd89220de53
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Fix Linux daemon install checks when systemd user bus env is missing (#34884)

* daemon(systemd): fall back to machine user scope when user bus is missing

* test(systemd): cover machine scope fallback for user-bus errors

* test(systemd): reset execFile mock state across cases

* test(systemd): make machine-user fallback assertion portable

* fix(daemon): keep root sudo path on direct user scope

* test(systemd): cover sudo root user-scope behavior

* ci: use resolvable bun version in setup-node-env

* agents: preserve totalTokens on request failure instead of using contextWindow (#34275)

Merged via squash.

Prepared head SHA: f9d111d0a79a07815d476356e98a28df3a0000ba
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix: align AGENTS.md template section names with post-compaction extraction (#25029) (#25098)

Merged via squash.

Prepared head SHA: 8cd6cc8049aab5a94d8a9d5fb08f2e792c4ac5fd
Co-authored-by: echoVic <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Changelog: add daemon systemd user-bus fallback entry (#34884)

* Changelog: add gateway restart health entry (#34874)

* fix: finalize spanish locale support

* fix: add spanish locale support (#35038) (thanks @DaoPromociones)

* fix(deps): patch hono transitive audit vulnerabilities

* fix(security): avoid prototype-chain account path checks (#34982)

Merged via squash.

Prepared head SHA: f89cc6a649959997fe1dec1e1c1bff9a61b2de98
Co-authored-by: HOYALIM <[email protected]>
Co-authored-by: dvrshil <[email protected]>
Reviewed-by: @dvrshil

* fix(deps): bump tar to 7.5.10

* docs(changelog): document dependency security fixes

* fix: restore auto-reply system events timeline (#34794) (thanks @anisoptera) (#34794)

Co-authored-by: Ayaan Zaidi <[email protected]>

* fix(feishu): comprehensive reply mechanism — outbound replyToId forwarding + topic-aware reply targeting (#33789)

* fix(feishu): comprehensive reply mechanism fix — outbound replyToId forwarding + topic-aware reply targeting

- Forward replyToId from ChannelOutboundContext through sendText/sendMedia
  to sendMessageFeishu/sendMarkdownCardFeishu/sendMediaFeishu, enabling
  reply-to-message via the message tool.

- Fix group reply targeting: use ctx.messageId (triggering message) in
  normal groups to prevent silent topic thread creation (#32980). Preserve
  ctx.rootId targeting for topic-mode groups (group_topic/group_topic_sender)
  and groups with explicit replyInThread config.

- Add regression tests for both fixes.

Fixes #32980
Fixes #32958
Related #19784

* fix: normalize Feishu delivery.to before comparing with messaging tool targets

- Add normalizeDeliveryTarget helper to strip user:/chat: prefixes for Feishu
- Apply normalization in matchesMessagingToolDeliveryTarget before comparison
- This ensures cron duplicate suppression works when session uses prefixed targets
  (user:ou_xxx) but messaging tool extract uses normalized bare IDs (ou_xxx)

Fixes review comment on PR #32755

(cherry picked from commit fc20106f16ccc88a5f02e58922bb7b7999fe9dcd)

* fix(feishu): catch thrown SDK errors for withdrawn reply targets

The Feishu Lark SDK can throw exceptions (SDK errors with .code or
AxiosErrors with .response.data.code) for withdrawn/deleted reply
targets, in addition to returning error codes in the response object.

Wrap reply calls in sendMessageFeishu and sendCardFeishu with
try-catch to handle thrown withdrawn/not-found errors (230011,
231003) and fall back to client.im.message.create, matching the
existing response-level fallback behavior.

Also extract sendFallbackDirect helper to deduplicate the
direct-send fallback block across both functions.

Closes #33496

(cherry picked from commit ad0901aec103a2c52f186686cfaf5f8ba54b4a48)

* feishu: forward outbound reply target context

(cherry picked from commit c129a691fcf552a1cebe1e8a22ea8611ffc3b377)

* feishu extension: tighten reply target fallback semantics

(cherry picked from commit f85ec610f267020b66713c09e648ec004b2e26f1)

* fix(feishu): align synthesized fallback typing and changelog attribution

* test(feishu): cover group_topic_sender reply targeting

---------

Co-authored-by: Xu Zimo <[email protected]>
Co-authored-by: Munem Hashmi <[email protected]>
Co-authored-by: bmendonca3 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(feishu): use msg_type media for mp4 video (fixes #33674) (#33720)

* fix(feishu): use msg_type media for mp4 video (fixes #33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw/openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(agents): bypass pendingDescendantRuns guard for cron announce delivery (#35185)

* fix(agents): bypass pendingDescendantRuns guard for cron announce delivery

Standalone cron job completions were blocked from direct channel delivery
when the cron run had spawned subagents that were still registered as
pending. The pendingDescendantRuns guard exists for live orchestration
coordination and should not apply to fire-and-forget cron announce sends.

Thread the announceType through the delivery chain and skip both the
child-descendant and requester-descendant pending-run guards when the
announce originates from a cron job.

Closes #34966

* fix: ensure outbound session entry for cron announce with named agents (#32432)

Named agents may not have a session entry for their delivery target,
causing the announce flow to silently fail (delivered=false, no error).

Two fixes:
1. Call ensureOutboundSessionEntry when resolving the cron announce
   session key so downstream delivery can find channel metadata.
2. Fall back to direct outbound delivery when announce delivery fails
   to ensure cron output reaches the target channel.

Closes #32432

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: guard announce direct-delivery fallback against suppression leaks (#32432)

The `!delivered` fallback condition was too broad — it caught intentional
suppressions (active subagents, interim messages, SILENT_REPLY_TOKEN) in
addition to actual announce delivery failures.  Add an
`announceDeliveryWasAttempted` flag so the direct-delivery fallback only
fires when `runSubagentAnnounceFlow` was actually called and failed.

Also remove the redundant `if (route)` guard in
`resolveCronAnnounceSessionKey` since `resolved` being truthy guarantees
`route` is non-null.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix(cron): harden announce synthesis follow-ups

---------

Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* Feishu: harden streaming merge semantics and final reply dedupe (#33245)

* Feishu: close duplicate final gap and cover routing precedence

* Feishu: resolve reviewer duplicate-final and routing feedback

* Feishu: tighten streaming send-mode option typing

* Feishu: fix reverse-overlap streaming merge ordering

* Feishu: align streaming final dedupe test expectation

* Feishu: allow distinct streaming finals while deduping repeats

---------

Co-authored-by: Tak Hoffman <[email protected]>

* fix: cron backup should preserve pre-edit snapshot (#35195) (#35234)

* fix(cron): avoid overwriting .bak during normalization

Fixes openclaw/openclaw#35195

* test(cron): preserve pre-edit bak snapshot in normalization path

---------

Co-authored-by: 0xsline <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(cron): stabilize restart catch-up replay semantics (#35351)

* Cron: stabilize restart catch-up replay semantics

* Cron: respect backoff in startup missed-run replay

* cron: narrow startup replay backoff guard (#35391)

* cron: unify stale-run recovery and preserve manual-run every anchors (#35363)

* cron: unify stale-run recovery and preserve manual every anchors

* cron: address unresolved review threads on recovery paths

* cron: remove duplicate timestamp helper after rebase

* refactor(telegram): remove unused webhook callback helper (#27816)

* fix(pr): make review claim step required

* fix(skills): deduplicate slash commands by skillName across all interfaces

Move skill-command deduplication by skillName from the Discord-only
`dedupeSkillCommandsForDiscord` into `listSkillCommandsForAgents` so
every interface (TUI, Slack, text) consistently sees a clean command
list without platform-specific workarounds.

When multiple agents share a skill with the same name the old code
emitted `github` + `github_2` and relied on Discord to collapse them.
Now `listSkillCommandsForAgents` returns only the first registration
per skillName, and the Discord-specific wrapper is removed.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* style: fix formatting in skill-commands.test.ts and provider.ts

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* style(skills): align formatting cleanup for dedupe changes

* chore(changelog): add dedupe note openclaw#27521 thanks @shivama205

* fix(agents): detect Venice provider proxying xAI/Grok models for schema cleaning (#35355)

Merged via squash.

Prepared head SHA: 8bfdec257bb6a6025cb69a0a213a433da32b15db
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(agents): decode HTML entities in xAI/Grok tool call arguments (#35276)

Merged via squash.

Prepared head SHA: c4445d2938898ded9c046614f9315dbda65ec573
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(agents): guard promoteThinkingTagsToBlocks against malformed content entries (#35143)

Merged via squash.

Prepared head SHA: 3971122f5fd27c66c8c9c5ce783f00e113b1f47b
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(web-ui): render Accounts schema node properly (#35380)

Co-authored-by: stakeswky <[email protected]>
Co-authored-by: liuxiaopai-ai <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(agents): guard context pruning against malformed thinking blocks (#35146)

Merged via squash.

Prepared head SHA: a196a565b1b8e806ffbf85172bcf1128796b45a2
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(gateway): prevent internal route leakage in chat.send

Synthesis of routing fixes from #35321, #34635, and #35356 for internal-client reply safety.

- Require explicit `deliver: true` before inheriting any external delivery route.
- Keep webchat/TUI/UI-origin traffic on internal routing by default.
- Allow configured-main session inheritance only for non-Webchat/UI clients, and honor `session.mainKey`.
- Add regression tests for UI no-inherit, configured-main CLI inherit, and deliver-flag behavior.

Co-authored-by: alexyyyander <[email protected]>
Co-authored-by: Octane0411 <[email protected]>
Co-authored-by: Linux2010 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(gateway): pass actual version to Control UI client instead of dev (#35230)

* fix(gateway): pass actual version to Control UI client instead of "dev"

The GatewayClient, CLI WS client, and browser Control UI all sent
"dev" as their clientVersion during handshake, making it impossible
to distinguish builds in gateway logs and health snapshots.

- GatewayClient and CLI WS client now use the resolved VERSION constant
- Control UI reads serverVersion from the bootstrap endpoint and
  forwards it when connecting
- Bootstrap contract extended with serverVersion field

Closes #35209

* Gateway: fix control-ui version version-reporting consistency

* Control UI: guard deferred bootstrap connect after disconnect

* fix(ui): accept same-origin http and relative gateway URLs for client version

---------

Co-authored-by: Tak Hoffman <[email protected]>

* chore(pr): enforce changelog placement and reduce merge sync churn

* TTS: add baseUrl support to OpenAI TTS config (#34321)

Merged via squash.

Prepared head SHA: e9a10cf81d2021cf81091dfa81e13ffdbb6a540a
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* ACP: add persistent Discord channel and Telegram topic bindings (#34873)

* docs: add ACP persistent binding experiment plan

* docs: align ACP persistent binding spec to channel-local config

* docs: scope Telegram ACP bindings to forum topics only

* docs: lock bound /new and /reset behavior to in-place ACP reset

* ACP: add persistent discord/telegram conversation bindings

* ACP: fix persistent binding reuse and discord thread parent context

* docs: document channel-specific persistent ACP bindings

* ACP: split persistent bindings and share conversation id helpers

* ACP: defer configured binding init until preflight passes

* ACP: fix discord thread parent fallback and explicit disable inheritance

* ACP: keep bound /new and /reset in-place

* ACP: honor configured bindings in native command flows

* ACP: avoid configured fallback after runtime bind failure

* docs: refine ACP bindings experiment config examples

* acp: cut over to typed top-level persistent bindings

* ACP bindings: harden reset recovery and native command auth

* Docs: add ACP bound command auth proposal

* Tests: normalize i18n registry zh-CN assertion encoding

* ACP bindings: address review findings for reset and fallback routing

* ACP reset: gate hooks on success and preserve /new arguments

* ACP bindings: fix auth and binding-priority review findings

* Telegram ACP: gate ensure on auth and accepted messages

* ACP bindings: fix session-key precedence and unavailable handling

* ACP reset/native commands: honor fallback targets and abort on bootstrap failure

* Config schema: validate ACP binding channel and Telegram topic IDs

* Discord ACP: apply configured DM bindings to native commands

* ACP reset tails: dispatch through ACP after command handling

* ACP tails/native reset auth: fix target dispatch and restore full auth

* ACP reset detection: fallback to active ACP keys for DM contexts

* Tests: type runTurn mock input in ACP dispatch test

* ACP: dedup binding route bootstrap and reset target resolution

* reply: align ACP reset hooks with bound session key

* docs: replace personal discord ids with placeholders

* fix: add changelog entry for ACP persistent bindings (#34873) (thanks @dutifulbob)

---------

Co-authored-by: Onur <[email protected]>

* docs(telegram): recommend allowlist for single-user DM policy (#34841)

* docs(telegram): recommend allowlist for single-user bots

* docs(telegram): condense single-user allowlist note

---------

Co-authored-by: echoVic <[email protected]>

* fix(feishu): check response.ok before calling response.json() in streaming card (#35628)

Merged via squash.

Prepared head SHA: 62c3fec80d97cea9be344c0bef5358a0a5dc5560
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Mattermost: honor onmessage mention override and add gating diagnostics tests (#27160)

Merged via squash.

Prepared head SHA: 6cefb1d5bf3d6dfcec36c1cee3f9ea887f10c890
Co-authored-by: turian <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* fix(subagents): strip leaked [[reply_to]] tags from completion announces (#34503)

* fix(subagents): strip reply tags from completion delivery text

* test(subagents): cover reply-tag stripping in cron completion sends

* changelog: note iMessage reply-tag stripping in completion announces

* Update CHANGELOG.md

* Apply suggestion from @greptile-apps[bot]

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix(cron): restore direct fallback after announce failure in best-effort mode (openclaw#36177)

Verified:
- pnpm build
- pnpm check (fails on pre-existing origin/main lint debt in extensions/mattermost imports)
- pnpm test:macmini

Co-authored-by: Tak Hoffman <[email protected]>

* test(cron): add cross-channel announce fallback regression coverage (openclaw#36197)

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check (fails on pre-existing origin/main lint debt in extensions/mattermost imports)
- pnpm test:macmini

Co-authored-by: Tak Hoffman <[email protected]>

* feat(mattermost): add interactive buttons support (#19957)

Merged via squash.

Prepared head SHA: 8a25e608729d0b9fd07bb0ee4219d199d9796dbe
Co-authored-by: tonydehnke <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* fix(browser): remove deprecated --disable-blink-features=AutomationControlled flag

- Removes OpenClaw's default `--disable-blink-features=AutomationControlled` Chrome launch switch to avoid unsupported-flag warnings in newer Chrome (#35721).
- Preserves compatibility for older Chrome via `browser.extraArgs` override behavior (source analysis: #35770, #35728, #35727, #35885).
- Synthesis attribution: thanks @Sid-Qin, @kevinWangSheng, @ningding97, @Naylenv, @clawbie.

Source PR refs: #35734, #35770, #35728, #35727, #35885

Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: kevinWangSheng <[email protected]>
Co-authored-by: ningding97 <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: clawbie <[email protected]>
Co-authored-by: Takhoffman <[email protected]>

* fix(feishu): add HTTP timeout to prevent per-chat queue deadlocks (#36430)

When the Feishu API hangs or responds slowly, the sendChain never settles,
causing the per-chat queue to remain in a processing state forever and
blocking all subsequent messages in that thread. This adds a 30-second
default timeout to all Feishu HTTP requests by providing a timeout-aware
httpInstance to the Lark SDK client.

Closes #36412

Co-authored-by: Ayane <[email protected]>

* fix(feishu): use probed botName for mention checks (#36391)

* Feishu: honor bot mentions by ID despite aliases (Fixes #36317) (#36333)

* Mattermost: switch plugin-sdk imports to scoped subpaths (openclaw#36480)

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(feishu): accept groupPolicy "allowall" as alias for "open" (#36358)

* fix(feishu): accept groupPolicy "allowall" as alias for "open"

When users configure groupPolicy: "allowall" in Feishu channel config,
the Zod schema rejects the value and the runtime policy check falls
through to the allowlist path.  With an empty allowFrom array, all group
messages are silently dropped despite the intended "allow all" semantics.

Accept "allowall" at the schema level (transform to "open") and add a
runtime guard in isFeishuGroupAllowed so the value is handled even if it
bypasses schema validation.

Closes #36312

Made-with: Cursor

* Feishu: tighten allowall alias handling and coverage

---------

Co-authored-by: Tak Hoffman <[email protected]>

* synthesis: fix Feishu group mention slash parsing

## Summary\n\nFeishu group slash command parsing is fixed for mentions and command probes across authorization paths.\n\nThis includes:\n- Normalizing bot mention text in group context for reliable slash detection in message parsing.\n- Adding command-probe normalization for group slash invocations.\n\nCo-authored-by: Sid Qin <[email protected]>\nCo-authored-by: Tak Hoffman <[email protected]>

* Feishu: normalize group slash command probing

- Feishu/group slash command detection: normalize group mention wrappers before command-authorization probing so mention-prefixed commands are recognized in group routing.\n- Source PR: #36011\n- Contributor: @liuxiaopai-ai\n\nCo-authored-by: Tak Hoffman <[email protected]>\nCo-authored-by: liuxiaopai-ai <[email protected]>

* add prependSystemContext and appendSystemContext to before_prompt_build (fixes #35131) (#35177)

Merged via squash.

Prepared head SHA: d9a2869ad69db9449336a2e2846bd9de0e647ac6
Co-authored-by: maweibin <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(feishu): avoid media regressions from global HTTP timeout (#36500)

* fix(feishu): avoid media regressions from global http timeout

* fix(feishu): source HTTP timeout from config

* fix(feishu): apply media timeout override to image uploads

* fix(feishu): invalidate cached client when timeout changes

* fix(feishu): clamp timeout values and cover image download

* chore(devcontainer): add claude-code extension and set Ollama context window to 16384

---------

Signed-off-by: HCL <[email protected]>
Co-authored-by: Viz <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
Co-authored-by: Shadow <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: bmendonca3 <[email protected]>
Co-authored-by: davidahmann <[email protected]>
Co-authored-by: harshang03 <[email protected]>
Co-authored-by: haosenwang1018 <[email protected]>
Co-authored-by: liuxiaopai-ai <[email protected]>
Co-authored-by: coygeek <[email protected]>
Co-authored-by: lailoo <[email protected]>
Co-authored-by: Henry Loenwind <[email protected]>
Co-authored-by: HenryLoenwind <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: JT <[email protected]>
Co-authored-by: Josh Lehman <[email protected]>
Co-authored-by: Eugene <[email protected]>
Co-authored-by: sircrumpet <[email protected]>
Co-authored-by: Muhammed Mukhthar CM <[email protected]>
Co-authored-by: Gustavo Madeira Santana <[email protected]>
Co-authored-by: Sid <[email protected]>
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: Nimrod Gutman <[email protected]>
Co-authored-by: KimGLee <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
Co-authored-by: Altay <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Co-authored-by: OpenCils <[email protected]>
Co-authored-by: chengzhichao-xydt <[email protected]>
Co-authored-by: chengzhichao-xydt <[email protected]>
Co-authored-by: jalehman <[email protected]>
Co-authored-by: Rodrigo Uroz <[email protected]>
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: Shadow <[email protected]>
Co-authored-by: Mylszd <[email protected]>
Co-authored-by: Jason L. West, Sr. <[email protected]>
Co-authored-by: jlwestsr <[email protected]
Takhoffman added a commit to Sid-Qin/openclaw that referenced this pull request Mar 5, 2026
…penclaw#33720)

* fix(feishu): use msg_type media for mp4 video (fixes openclaw#33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
zooqueen pushed a commit to hanzoai/bot that referenced this pull request Mar 6, 2026
…penclaw#33720)

* fix(feishu): use msg_type media for mp4 video (fixes openclaw#33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
thinstripe pushed a commit to thinstripe/openclaw that referenced this pull request Mar 6, 2026
…penclaw#33720)

* fix(feishu): use msg_type media for mp4 video (fixes openclaw#33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
handsdiff pushed a commit to handsdiff/activeclaw that referenced this pull request Mar 6, 2026
…penclaw#33720)

* fix(feishu): use msg_type media for mp4 video (fixes openclaw#33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
jenawant pushed a commit to jenawant/openclaw that referenced this pull request Mar 10, 2026
…penclaw#33720)

* fix(feishu): use msg_type media for mp4 video (fixes openclaw#33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
BenediktSchackenberg pushed a commit to BenediktSchackenberg/openclaw that referenced this pull request Mar 13, 2026
…penclaw#33720)

* fix(feishu): use msg_type media for mp4 video (fixes openclaw#33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
V-Gutierrez pushed a commit to V-Gutierrez/openclaw-vendor that referenced this pull request Mar 17, 2026
…penclaw#33720)

* fix(feishu): use msg_type media for mp4 video (fixes openclaw#33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 19, 2026
…penclaw#33720)

* fix(feishu): use msg_type media for mp4 video (fixes openclaw#33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 68e68bf)
alexey-pelykh pushed a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
…penclaw#33720)

* fix(feishu): use msg_type media for mp4 video (fixes openclaw#33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 68e68bf)
alexey-pelykh added a commit to remoteclaw/remoteclaw that referenced this pull request Mar 20, 2026
)

* iOS Security Stack 1/5: Keychain Migrations + Tests (#33029)

(cherry picked from commit ec0eb9f8c)

* iOS Security Stack 2/5: Concurrency Locks (#33241)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: b99ad804fbcc20bfb3042ac1da9050a7175f009c
Co-authored-by: mbelinky <[email protected]>
Co-authored-by: mbelinky <[email protected]>
Reviewed-by: @mbelinky

(cherry picked from commit 6df57d963366e053d5b9a9f649d553b4177b5798)

* iOS Security Stack 3/5: Runtime Security Guards (#33031)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: 99171654014d1960edcaca8312ef6a47d3c08399
Co-authored-by: mbelinky <[email protected]>
Co-authored-by: mbelinky <[email protected]>
Reviewed-by: @mbelinky

(cherry picked from commit a3112d6c5fa18313b25fe52df2abe9b6bf9ecfd0)

* iOS Security Stack 4/5: TTS PCM->MP3 Fallback (#30885) (#33032)

Merged via /review-pr -> /prepare-pr -> /merge-pr.

Prepared head SHA: f77e3d764425a23ab5d5b55593d9e14622f1ef95
Co-authored-by: mbelinky <[email protected]>
Co-authored-by: mbelinky <[email protected]>
Reviewed-by: @mbelinky

(cherry picked from commit bf7061092a1e507a22e9fabe5b7f3554dbe0acc6)

* docs(security): document Docker UFW hardening via DOCKER-USER (#27613)

Merged via squash.

Prepared head SHA: 31ddd433265d8a7efbf932c941678598bf6be30c
Co-authored-by: dorukardahan <[email protected]>
Co-authored-by: grp06 <[email protected]>
Reviewed-by: @grp06

(cherry picked from commit 2cd3be896d525e9f1343e15fa6e2bc5c3caf99a2)

* security: add X-Content-Type-Options nosniff header to media route (#30356)

Merged via squash.

Prepared head SHA: b14f9ad7ca7017c6e31fb18c8032a81f49686ea4
Co-authored-by: 13otKmdr <[email protected]>
Co-authored-by: grp06 <[email protected]>
Reviewed-by: @grp06

(cherry picked from commit a8dd9ffea174cbc8a034acd1c3bb3c7a40c72da9)

* docs: fix Mintlify-incompatible links in security docs (#27698)

Merged via squash.

Prepared head SHA: 6078cd94ba38b49d17e9680073337885c5f9e781
Co-authored-by: clawdoo <[email protected]>
Co-authored-by: grp06 <[email protected]>
Reviewed-by: @grp06

(cherry picked from commit b1a735829d78083447e70eee06e68670154ddd1e)

* fix(security): strip partial API token from status labels (#33262)

Merged via squash.

Prepared head SHA: 5fe81704e678dc5b18ca9416e5eb0750cfe49fb6
Co-authored-by: cu1ch3n <[email protected]>
Co-authored-by: grp06 <[email protected]>
Reviewed-by: @grp06

(cherry picked from commit e8cb0484ce6c0e43a8e7ce3a6fdfba4c04c4be54)

* feat(gateway): add Permissions-Policy header to default security headers (#30186)

Merged via squash.

Prepared head SHA: 0dac89283f54840ec2244007ff5a6178ce8b2ba9
Co-authored-by: habakan <[email protected]>
Co-authored-by: grp06 <[email protected]>
Reviewed-by: @grp06

(cherry picked from commit 4b17d6d8823c524ff1c3c3fa49a465cba5b560c1)

* fix: revert acceptsArgs test assertion from gutted model-auth-label

The upstream commit e8cb0484c added acceptsArgs to model-auth-label.ts
(gutted in fork) and its test expectation in commands.test.ts. Since the
production code path that populates acceptsArgs was discarded, revert
the test assertion to match.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(gateway): flush throttled delta before emitChatFinal (#24856)

(cherry picked from commit a9ec75fe8)

* Gateway: fix stale self version in status output (#32655)

Merged via squash.

Prepared head SHA: b9675d1f90ef0eabb7e68c24a72d4b2fb27def22
Co-authored-by: liuxiaopai-ai <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

(cherry picked from commit ae298421583b96031d4f2be45d11e1d1105e1fdd)

* macOS: add tailscale serve discovery fallback for remote gateways (#32860)

(cherry picked from commit 4aa548cf7)

* fix(gateway): include disk-scanned agent IDs in listConfiguredAgentIds (#32831)

Merged via squash.

Prepared head SHA: 2aa58f6afd6e7766119575648483de6b5f50da6f
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

(cherry picked from commit 3ad3a90db31dd5c6466bee33b7ae3ffab051baa2)

* fix(gateway): synthesize lifecycle robustness for restart and startup probes (#33831)

* fix(gateway): correct launchctl command sequence for gateway restart (closes #20030)

* fix(restart): expand HOME and escape label in launchctl plist path

* fix(restart): poll port free after SIGKILL to prevent EADDRINUSE restart loop

When cleanStaleGatewayProcessesSync() kills a stale gateway process,
the kernel may not immediately release the TCP port. Previously the
function returned after a fixed 500ms sleep (300ms SIGTERM + 200ms
SIGKILL), allowing triggerOpenClawRestart() to hand off to systemd
before the port was actually free. The new systemd process then raced
the dying socket for port 18789, hit EADDRINUSE, and exited with
status 1, causing systemd to retry indefinitely — the zombie restart
loop reported in #33103.

Fix: add waitForPortFreeSync() that polls lsof at 50ms intervals for
up to 2 seconds after SIGKILL. cleanStaleGatewayProcessesSync() now
blocks until the port is confirmed free (or the budget expires with a
warning) before returning. The increased SIGTERM/SIGKILL wait budgets
(600ms / 400ms) also give slow processes more time to exit cleanly.

Fixes #33103
Related: #28134

* fix: add EADDRINUSE retry and TIME_WAIT port-bind checks for gateway startup

* fix(ports): treat EADDRNOTAVAIL as non-retryable and fix flaky test

* fix(gateway): hot-reload agents.defaults.models allowlist changes

The reload plan had a rule for `agents.defaults.model` (singular) but
not `agents.defaults.models` (plural — the allowlist array).  Because
`agents.defaults.models` does not prefix-match `agents.defaults.model.`,
it fell through to the catch-all `agents` tail rule (kind=none), so
allowlist edits in openclaw.json were silently ignored at runtime.

Add a dedicated reload rule so changes to the models allowlist trigger
a heartbeat restart, which re-reads the config and serves the updated
list to clients.

Fixes #33600

Co-authored-by: HCL <[email protected]>
Signed-off-by: HCL <[email protected]>

* test(restart): 100% branch coverage — audit round 2

Audit findings fixed:
- remove dead guard: terminateStaleProcessesSync pids.length===0 check was
  unreachable (only caller cleanStaleGatewayProcessesSync already guards)
- expose __testing.callSleepSyncRaw so sleepSync's real Atomics.wait path
  can be unit-tested directly without going through the override
- fix broken sleepSync Atomics.wait test: previous test set override=null
  but cleanStaleGatewayProcessesSync returned before calling sleepSync —
  replaced with direct callSleepSyncRaw calls that actually exercise L36/L42-47
- fix pid collision: two tests used process.pid+304 (EPERM + dead-at-SIGTERM);
  EPERM test changed to process.pid+305
- fix misindented tests: 'deduplicates pids' and 'lsof status 1 container
  edge case' were outside their intended describe blocks; moved to correct
  scopes (findGatewayPidsOnPortSync and pollPortOnce respectively)
- add missing branch tests:
  - status 1 + non-empty stdout with zero openclaw pids → free:true (L145)
  - mid-loop non-openclaw cmd in &&-chain (L67)
  - consecutive p-lines without c-line between them (L67)
  - invalid PID in p-line (p0 / pNaN) — ternary false branch (L67)
  - unknown lsof output line (else-if false branch L69)

Coverage: 100% stmts / 100% branch / 100% funcs / 100% lines (36 tests)

* test(restart): fix stale-pid test typing for tsgo

* fix(gateway): address lifecycle review findings

* test(update): make restart-helper path assertions windows-safe

---------

Signed-off-by: HCL <[email protected]>
Co-authored-by: Glucksberg <[email protected]>
Co-authored-by: Efe Büken <[email protected]>
Co-authored-by: Riccardo Marino <[email protected]>
Co-authored-by: HCL <[email protected]>
(cherry picked from commit 1be39d4250e3d124da12d0723705d0281b113c94)

* fix: substitute YYYY-MM-DD at session startup and post-compaction (#32363) (#32381)

Merged via squash.

Prepared head SHA: aee998a2c1a911d3fef771aa891ac315a2f7dc53
Co-authored-by: chengzhichao-xydt <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

(cherry picked from commit 53727c72f4d22e39b5eba07efc78e66344605c2a)

* fix(routing): unify session delivery invariants for duplicate suppression (#33786)

(cherry picked from commit 7f2708a8c)

* fix(gateway+acp): thread stopReason through final event to ACP bridge (#24867)

Complete the stop reason propagation chain so ACP clients can
distinguish end_turn from max_tokens:

- server-chat.ts: emitChatFinal accepts optional stopReason param,
  includes it in the final payload, reads it from lifecycle event data
- translator.ts: read stopReason from the final payload instead of
  hardcoding end_turn

Chain: LLM API → run.ts (meta.stopReason) → agent.ts (lifecycle event)
→ server-chat.ts (final payload) → ACP translator (PromptResponse)

(cherry picked from commit 0b3bbfec061f55a65975b6dce77c04dba1925f9c)

* fix: resolve CI build and test failures from cherry-picks

- Add threadId to MessagingToolSend type (needed by reply-payloads)
- Remove shouldHideHeartbeatChatOutput call (function not in fork)
- Rebrand OpenClawConfig to RemoteClawConfig in auto-merged test files
- Rebrand openclaw to remoteclaw in restart-stale-pids test fixtures
- Rebrand OPENCLAW_LAUNCHD_LABEL to REMOTECLAW_LAUNCHD_LABEL in test

* fix(heartbeat): scope exec wake dispatch to session key (#32724)

Merged via squash.

Prepared head SHA: 563fee0e65af07575f3df540cab2e1e5d5589f06
Co-authored-by: altaywtf <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

(cherry picked from commit 627813aba499a57acdbee8bdc670f7edb030c9eb)

* fix(config): detect top-level heartbeat as invalid config path (#30894) (#32706)

Merged via squash.

Prepared head SHA: 1714ffe6fc1e3ed6a8a120d01d074f1be83c62d3
Co-authored-by: xiwan <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

(cherry picked from commit caa748b9694f64d30d6aa1fa1b724f8e2b3ae579)

* fix: resolve CI build failures from cherry-picks

- Remove bash-tools.exec-runtime.test.ts (imports from gutted module)
- Fix OpenClawConfig → RemoteClawConfig in heartbeat scheduler test

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: ignore discord wildcard audit keys (#33125) (thanks @thewilloftheshadow) (#33125)

(cherry picked from commit 8e2e4b2ed58cd7128f770fcf7fb4ffcf874af715)

* fix: Discord acp inline actions + bound-thread filter (#33136) (thanks @thewilloftheshadow) (#33136)

(cherry picked from commit 4abf398a17ad127935236f4f072a93e890e5581e)

* fix: harden Discord channel resolution (#33142) (thanks @thewilloftheshadow) (#33142)

(cherry picked from commit ca307c3fdf8a03869b3848bc01675f26e3dfed71)

* docs(loop-detection): fix config keys to match schema (#33182)

Merged via squash.

Prepared head SHA: 612ecc00d36cbbefb0657f0a2ac0898d53a5ed73
Co-authored-by: Mylszd <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

(cherry picked from commit d89e1e40f9d8d33d68bd146802d13827e5989b58)

* fix: improve discord chunk delivery (#33226) (thanks @thewilloftheshadow) (#33226)

(cherry picked from commit 6593a576074c6bbf376efa6ca5f9f09fa2e8faf9)

* fix(discord): default presence online when unconfigured

(cherry picked from commit 5d16d45b20408ce851b3df70994c8e0ec24fb275)

* fix(discord): stop typing after silent runs

(cherry picked from commit 66d06beec6f61fab49d6f77ffeed745c5750a771)

* fix(discord): use fetch for voice upload slots

(cherry picked from commit 3b3738e41e2d2469bfa700318f880d5b9537ef56)

* test(discord): align bound-thread target kind

(cherry picked from commit 3ee8528b17cd1a75cc1f431e24105a4c46a57ed3)

* fix: discord mention handling (#33224) (thanks @thewilloftheshadow) (#33224)

(cherry picked from commit d493861c1692664ce7882516cf952fcb8dc02b67)

* fix: allowlist Discord CDN hostnames for SSRF media (#33275) (thanks @thewilloftheshadow) (#33275)

(cherry picked from commit a7a9a3d3c84a444977c8c70d93c89406aaf01f06)

* fix: discord auto presence health signal (#33277) (thanks @thewilloftheshadow) (#33277)

(cherry picked from commit e28ff1215cf5cc43894269f23af09862ac1a965f)

* docs: document discord ignoreOtherMentions

(cherry picked from commit 05446d6b6bc318147bca058f5f72a6f13937ffea)

* fix(discord): skip bot messages before debounce

(cherry picked from commit 548b15d8e080dbb58775b4a16f8660460dc41b59)

* fix(discord): honor agent media roots in replies

(cherry picked from commit 0eef7a367dc371980cdc8d5cdf2d637aa6882b00)

* fix(discord): harden slash command routing

(cherry picked from commit b8b1eeb052fdbda2ea2d9f56892c7d53916a6338)

* fix(discord): reset thread sessions on archive

(cherry picked from commit 16ebbd24b5fdaa5c21efc407c1ba7e6a8b383049)

* fix: drop discord opus dependency

(cherry picked from commit b0bcea03dbf4743cf67bac55c1d793d86b0684df)

* feat(discord): add allowBots mention gating

(cherry picked from commit 65816657c2ae799064a16d5353942eb91c6e35d3)

* fix(discord): align DiscordAccountConfig.token type with SecretInput (#32490)

Merged via squash.

Prepared head SHA: 233aa032f1d894b7eb6a960247baa1336f8fbc26
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: joshavant <[email protected]>
Reviewed-by: @joshavant

(cherry picked from commit ff96e41c38b90f5aba54472cbaf93e773204b8ae)

* Runtime: stabilize tool/run state transitions under compaction and backpressure

(cherry picked from commit 9889c6da53 — partial: gutted pi-embedded-helpers discarded)

* fix(ci): use HTTPS for libsignal-node git dep (SSH unavailable in CI)

* fix(ci): resolve fork import paths for auto-presence + fix acceptsArgs test assertion

* fix(ci): adapt discord cherry-picks to fork rebrand (RemoteClawConfig, SecretInput, mock types)

* fix(ci): resolve remaining fork adaptation issues (auth imports, type mismatches, missing imports)

* fix(ci): cast ThreadBindingRecord to SessionBindingRecord in preflight test

* fix: scope extension runtime deps to plugin manifests

(cherry picked from commit e1503349c3b741970a5cf2cd9038b8e7093f2a41)

* plugin-sdk: add channel subpaths and migrate bundled plugins

(cherry picked from commit 1278ee924)

* fix(line): synthesize media/auth/routing webhook regressions (openclaw#32546) thanks @Takhoffman

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 9a5bfb1fe56d9000a6e089bf0c3fca8081710bb0)

* security(line): synthesize strict LINE auth boundary hardening

(cherry picked from commit dbccc73d7)

* fix(extensions): synthesize mediaLocalRoots propagation across sendMedia adapters

Restore deterministic mediaLocalRoots propagation through extension sendMedia adapters and add coverage for local/remote media handling in Google Chat.

Synthesis of #33581, #33545, #33540, #33536, #33528.

Co-authored-by: bmendonca3 <[email protected]>
(cherry picked from commit 87e6ce7c3a2f166eb1abec967ae20682e0d37ced)

* fix(ios): guard talk TTS callbacks to active utterance (#33304)

(cherry picked from commit 22e33ddda)

* fix: resolve CI build failures from cherry-picks

- Fix googlechat peerDependencies version to use workspace:*
- Regenerate pnpm-lock.yaml for lockfile consistency

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix: resolve CI build failures from cherry-picks

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* ci: enable stale workflow (#1675)

(cherry picked from commit 2a888c5703ea58efe884186367227af8b3b06acc)

Co-authored-by: Shadow <[email protected]>

* fix(ci): handle disabled systemd units in docker doctor flow (#1676)

(cherry picked from commit b52c9f2575b68cf5e70c90750a2dd685c00dcafc)

Co-authored-by: Peter Steinberger <[email protected]>

* docs(contributing): require before/after screenshots for UI PRs (#32206) (#1677)

Merged via squash.

Prepared head SHA: d7f0914873aec1c3c64c9161771ff0bcbc457c95
Co-authored-by: hydro13 <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

(cherry picked from commit 44162e7ba564bd68bfecd68050ec594949a92358)

Co-authored-by: Robin Waslander <[email protected]>

* docs: fix secretref marker rendering in credential surface (#1678)

(cherry picked from commit a9969e641add3b650198dfb63f084b7583c9881e)

Adaptation: discarded src/secrets/target-registry.test.ts (gutted layer),
rebranded OpenClaw→RemoteClaw and openclaw.json→remoteclaw.json references.

Co-authored-by: joshavant <[email protected]>

* Cherry-pick 5341b5c71: Diffs — migrate tool guidance to plugin skill (#1679)

* Diffs: Migrate tool usage guidance from before_prompt_build to a plugin skill (#32630)

Cherry-picked from openclaw/openclaw@5341b5c71c (partial).
Kept: docs/tools/diffs.md, src/agents/skills.loadworkspaceskillentries.test.ts.
Discarded gutted extension files.
Rebranded openclaw → remoteclaw in paths and env vars.

Co-authored-by: sircrumpet <[email protected]>
Co-authored-by: gumadeiras <[email protected]>

* fix(cherry-pick): drop skills test — loadWorkspaceSkillEntries gutted in fork

The test file imports ./skills.js which was removed during the skills
system gut (feat: gut skills system and ClawHub #63). Remove to fix
type-check failure.

---------

Co-authored-by: Eugene <[email protected]>
Co-authored-by: sircrumpet <[email protected]>
Co-authored-by: gumadeiras <[email protected]>

* Extensions: migrate bluebubbles plugin-sdk imports

(cherry picked from commit ff38bc7649ec7cfb1eb7a4cc8d7a49aa8b1cdfc6)

* Extensions: migrate device-pair plugin-sdk imports

(cherry picked from commit 2bb63868c6278d1f94bb92267cc10b7b19343809)

* Extensions: migrate diagnostics-otel plugin-sdk imports

(cherry picked from commit 56d98a50cfff2aee9b8e36bde12b9537783b7692)

* Extensions: migrate feishu plugin-sdk imports

(cherry picked from commit 1ebd1fdb2d4006f9ac8384a81e440e29b45bbfca)

* Extensions: migrate googlechat plugin-sdk imports

(cherry picked from commit 39a55844bc5dc02da225adad0b37c00f5d5f53ff)

* Extensions: migrate irc plugin-sdk imports

(cherry picked from commit 9b6101e382671fe5c8693d85e5fe28a2ad7e63bc)

* Extensions: migrate matrix plugin-sdk imports

(cherry picked from commit 15f7e329c24e4e51feb95f8b66b407cf06b02ef3)

* Extensions: migrate mattermost plugin-sdk imports

(cherry picked from commit 009d4d115ada6825e6b6a8ac0b08d24d50d3da16)

* Extensions: migrate msteams plugin-sdk imports

(cherry picked from commit 10bd6ae3c8e110027208aa3ff0b1d6d0b5363afb)

* Extensions: migrate nextcloud-talk plugin-sdk imports

(cherry picked from commit ed29472af6176f4ef3705c9e6e85c132e5a95e6a)

* Extensions: migrate nostr plugin-sdk imports

(cherry picked from commit 612ca670da55cc27b1206bc97d1a25f041510595)

* Extensions: migrate synology-chat plugin-sdk imports

(cherry picked from commit 96b0fce27c03f974dd05cf451635d3416f57d426)

* Extensions: migrate telegram plugin-sdk imports

(cherry picked from commit 7a9754c9271dcb80da8ef39a2c1d85110dfea8ea)

* Extensions: migrate test-utils plugin-sdk imports

(cherry picked from commit 9bf08c926b70fe2e51925025ba98d17d74638f9b)

* Extensions: migrate tlon plugin-sdk imports

(cherry picked from commit b0bca8d6e95c97156c72185e030a29ab115b2654)

* Extensions: migrate twitch plugin-sdk imports

(cherry picked from commit 9d102b762e24558c0584ed84b33efa33c6e913a1)

* Extensions: migrate voice-call plugin-sdk imports

(cherry picked from commit b361cac7534782d52fcb582138e8dbe64b2679f3)

* Extensions: migrate zalo plugin-sdk imports

(cherry picked from commit dda86af8664f30e7d37ffa359849984a583ec47d)

* Extensions: migrate zalouser plugin-sdk imports

(cherry picked from commit 37a8caee42bdb94292f6e00480d896e96764e407)

* Plugins/bluebubbles: migrate to scoped plugin-sdk imports

(cherry picked from commit 9cfec9c05ec33afec502a0665c08543975925d10)

* Plugins/device-pair: migrate to scoped plugin-sdk imports

(cherry picked from commit 04385a61b7760a91a1d384f5e2181b6ee35f9ef2)

* Plugins/diagnostics-otel: migrate to scoped plugin-sdk imports

(cherry picked from commit 54d78bb423d9f760cc66e8d13daed8da2ed68d44)

* Plugins/feishu: migrate to scoped plugin-sdk imports

(cherry picked from commit 3e1ca111afcdeb7b310122a962817e2c496c19df)

* Plugins/googlechat: migrate to scoped plugin-sdk imports

(cherry picked from commit a1e21bc02de28af52aa564cb32bd48fa96422e41)

* Plugins/irc: migrate to scoped plugin-sdk imports

(cherry picked from commit 7b8e36583fc7ffc54da90d398887d7392ea6b8c7)

* Plugins/matrix: migrate to scoped plugin-sdk imports

(cherry picked from commit b69b2a7ae0c40157ba6a31c77317e42f98a6d8ac)

* Plugins/mattermost: migrate to scoped plugin-sdk imports

(cherry picked from commit b1922762837af91b1cbdc74f6c80392dbee28794)

* Plugins/msteams: migrate to scoped plugin-sdk imports

(cherry picked from commit adb400f9b1f8a6fd0b1c1f8b813ddd44f72c39f8)

* Plugins/nextcloud-talk: migrate to scoped plugin-sdk imports

(cherry picked from commit 20ed90f1ba5326336c7273e316c028a123fcdd5b)

* Plugins/nostr: migrate to scoped plugin-sdk imports

(cherry picked from commit 3dda4aaf08bac5b05b149dc81b9e3c9df5823a2d)

* Plugins/phone-control: migrate to scoped plugin-sdk imports

(cherry picked from commit 71e62a77e8d45c675c01cf4096f74e2c696d7f54)

* Plugins/synology-chat: migrate to scoped plugin-sdk imports

(cherry picked from commit 65ffa676a51f58901eae0c64403ac8dc4e2b3734)

* Plugins/talk-voice: migrate to scoped plugin-sdk imports

(cherry picked from commit f006c5f5c1125b75b5f193906957e3a792a0ef5b)

* Plugins/test-utils: migrate to scoped plugin-sdk imports

(cherry picked from commit 8377dbba309b204ba6b1f2b3a370c2eae8a3ff55)

* Plugins/thread-ownership: migrate to scoped plugin-sdk imports

(cherry picked from commit 7c96d821129ad46e0a4f61e6e2d97923d95b9693)

* Plugins/tlon: migrate to scoped plugin-sdk imports

(cherry picked from commit 72e774431c1e425e34b64574aa429f9f88a2ceba)

* Plugins/twitch: migrate to scoped plugin-sdk imports

(cherry picked from commit a9af9334868da48869719ed9640abc6142bd1a90)

* Plugins/voice-call: migrate to scoped plugin-sdk imports

(cherry picked from commit bbf29201b8fefc507c7339421810fa61559743a6)

* Plugins/zalo: migrate to scoped plugin-sdk imports

(cherry picked from commit e9c7bb6e15185cdf40f19b66227c26beb362d06c)

* Plugins/zalouser: migrate to scoped plugin-sdk imports

(cherry picked from commit 5c4ab999b022b3a420b02276281be8970df17a3c)

* fix: revert per-extension plugin-sdk subpaths to barrel import

The upstream plugin-sdk scoped import migration introduced per-extension
subpath imports (e.g., plugin-sdk/zalouser) but the corresponding
subpath source files (src/plugin-sdk/{extension}.ts) haven't been
synced yet. Revert to barrel import (remoteclaw/plugin-sdk) until
those prerequisite commits are picked.

Also fixes OpenClawConfig → RemoteClawConfig references that leaked
through -X theirs conflict resolution.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(sessions-spawn): remove maxLength from attachment content schema to fix llama.cpp GBNF grammar overflow

(cherry picked from commit 965ce31d8472912d9eeeea3be87ce8b7d5ef5ed0)

* fix: harden sessions_spawn attachment schema landing (#33648) (thanks @anisoptera)

(cherry picked from commit 6962d2d79fedbbbed507f37b91bd3734cbdcc645)

* feat(web-search): switch Perplexity to native Search API (#33822)

* feat: Add Perplexity Search API as web_search provider

* docs fixes

* domain_filter validation

* address comments

* provider-specific options in cache key

* add validation for unsupported date filters

* legacy fields

* unsupported_language guard

* cache key matches the request's precedence order

* conflicting_time_filters guard

* unsupported_country guard

* invalid_date_range guard

* pplx validate for ISO 639-1 format

* docs: add Perplexity Search API changelog entry

* unsupported_domain_filter guard

---------

Co-authored-by: Shadow <[email protected]>
(cherry picked from commit 230fea1ca6c9b77c7facc3f8c4281e5e7c75dc38)

* fix: relay ACP sessions_spawn parent streaming (#34310) (thanks @vincentkoc) (#34310)

(cherry picked from commit 257e2f5338)

Fork note: excluded acp-spawn, acp-spawn-parent-stream, and
acp-agents docs — depend on control-plane infrastructure not present
in RemoteClaw. Kept doc and test updates for sessions tool schema.

* fix: prevent nodes media base64 context bloat (#34332)

(cherry picked from commit ef4fa43df89bf442abd134eca58cdefc18116190)

* fix(gateway): preserve route inheritance for legacy channel session keys (openclaw#33919) thanks @Takhoffman

Verified:
- pnpm build
- pnpm check
- pnpm test src/gateway/server-methods/chat.directive-tags.test.ts
- pnpm test:macmini

Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 8a7d1aa973b052bbb2e257caa51c18a4d2452b22)

* fix(gateway): narrow legacy route inheritance for custom session keys (openclaw#33932) thanks @Takhoffman

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit b4e4e25e74517e10bf370d8c3fb3d30aef968550)

* fix: code/cli acpx reliability 20260304 (#34020)

(cherry picked from commit 4d183af0cf790a9b6fc8107b7cafc6daa0dfb54e)

* fix(tui): normalize session key to lowercase to match gateway canonicalization (#34013)

Merged via squash.

Prepared head SHA: cfe06ca131661d1fd669270345c549ee8141cc46
Co-authored-by: lynnzc <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

(cherry picked from commit 9d941949c9ea47f3e6277aab744860d83f6c0dcd)

* fix: kill stuck ACP child processes on startup and harden sessions in discord threads (#33699)

(cherry picked from commit 61f7cea48b3e8e4b3e4ebc8d77daa27e7e57b97b)

* fix: preserve raw media invoke for HTTP tool clients (#34365)

(cherry picked from commit 7b5e64ef2e369258e2a4a613b7a62db3c21e5160)

* fixup: add missing eventQueueOpts definition and fix rebrand in test

- Add eventQueueOpts variable and eventQueue Client property (from upstream
  61f7cea48, lost in conflict resolution since it was in a code region that
  auto-merged without the variable definition)
- Fix lastCreateOpenClawToolsContext → lastCreateRemoteClawToolsContext rebrand

* fixup: add eventQueue property to DiscordAccountConfig type

Upstream added this property between picks; needed for commit 61f7cea48
which passes eventQueue opts to Carbon Client constructor.

* Deps: fix pnpm audit vulnerabilities in Google extension path (#33939)

* extensions/googlechat: require openclaw 2026.3.2+

* extensions/memory-core: require openclaw 2026.3.2+

* deps: bump fast-xml-parser override to 5.3.8

* deps: refresh lockfile for audit vulnerability fixes

(cherry picked from commit 4bc466422f045d63fdcb1dbac1b52a339254390f)

* docs(changelog): credit #31513 in #33647 entry

(cherry picked from commit d5a7a32826422b4764a97e1b7d810566c6e2908b)

* chore(docs): add plugins refactor changelog entry

(cherry picked from commit 6a40f69d4d823a26293ede43aa761b6ca9c29d56)

* docs(changelog): credit @Brotherinlaw-13 for #34318

(cherry picked from commit ed8e0a814609a070f46a0b6942dadc8e06ebf9d6)

* Delete changelog/fragments directory

(cherry picked from commit 88ee57124e9fcadbf987d423f5b82849441958b8)

* chore(changelog): add PR entry openclaw#24337 thanks @echoVic

(cherry picked from commit e6f0203ef395850fc459ce835f1a73c637ff03ca)

* Agents: add generic poll-vote action support

(cherry picked from commit 76bfd9b5e660a7ebfed3e258e849c9b2ec894b9f)

* Outbound: allow text-only plugin adapters

(cherry picked from commit efdf2ca0d79d10146429d040bc641f4fd2a5688d)

* Outbound: avoid empty multi-media fallback sends

(cherry picked from commit bb07b2b93a9ef2f1f1b5f3d29cb78b0579dc6f75)

* chore(changelog): align outbound adapter entry openclaw#32788 thanks @liuxiaopai-ai

(cherry picked from commit a970cae2dacebb5afb7e55d61abe2888db43d2d8)

* fix(outbound): fail media-only text-only adapter fallback

(cherry picked from commit 698c200eba2c88a76f349644e49e65f4424eb849)

* chore(changelog): clarify outbound media-only fallback openclaw#32788 thanks @liuxiaopai-ai

(cherry picked from commit 2123265c09f102763d1da955c22819ce4024e175)

* feat(telegram): add per-topic agent routing for forum groups [AI-assisted]

This feature allows different topics within a Telegram forum supergroup to route
to different agents, each with isolated workspace, memory, and sessions.

Key changes:
- Add agentId field to TelegramTopicConfig type for per-topic routing
- Add zod validation for agentId in topic config schema
- Implement routing logic to re-derive session key with topic's agent
- Add debug logging for topic agent overrides
- Add unit tests for routing behavior (forum topics + DM topics)
- Add config validation tests
- Document feature in docs/channels/telegram.md

This builds on the approach from PR #31513 by @Sid-Qin with additional fixes
for security (preserved account fail-closed guard) and test coverage.

Closes #31473

(cherry picked from commit 58bc9a241b7e68cb1df56b8b7c384e626634a78f)

* fix(telegram): address PR review comments

- Export pickFirstExistingAgentId and use it to validate topic agentId
- Properly update mainSessionKey when overriding route agent
- Fix docs example showing incorrect session key for topic 3

Fixes issue where non-existent agentId would create orphaned sessions.
Fixes issue where DM topic replies would route to wrong agent.

(cherry picked from commit 8eeb049683fb2639d0485129b2c6de7fca3d0f37)

* fix: tighten telegram topic-agent docs + fallback tests (#33647) (thanks @kesor)

(cherry picked from commit f74a04e4ba993860867f5b0a682b4289e2cddc04)

* fix(outbound): unify resolved cfg threading across send paths (#33987)

(cherry picked from commit 646817dd808b214eab635599a5c4909202f7bbd3)

* fix(telegram): materialize dm draft final to avoid duplicates

(cherry picked from commit 3cc1d5a92f481a6d93c686d7d013dfc5438ba868)

* rebrand: OpenClawConfig → RemoteClawConfig in cfg-threading paths

Fixup for 646817dd8 cherry-pick — upstream introduced OpenClawConfig
type refs across outbound send paths; align to fork naming.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* rebrand: fix type errors from cfg-threading cherry-pick

- OpenClawSchema → RemoteClawSchema in telegram topic test
- types.openclaw.js → types.remoteclaw.js in line/send.ts
- Wire resolveCommandSecretRefsViaGateway mock in message.test.ts
- Fix dmThreadId used-before-declaration in bot-message-context.ts

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* rebrand: fix telegram topic test direct → dms property name

Fork renamed `direct` to `dms` in telegram config schema.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* plugins: avoid peer auto-install dependency bloat (#34017) (#1686)

* plugins/install: omit peer deps during plugin npm install

* tests: assert plugin install omits peer deps

* extensions/googlechat: mark openclaw peer optional

* extensions/memory-core: mark openclaw peer optional

(cherry picked from commit dfb4cb87f9424787dc1a386e7b21050255d65add)

Co-authored-by: Vincent Koc <[email protected]>

* Cherry-pick 802b9f6b1: Plugins: add root-alias shim and cache/docs updates (#1687)

* Plugins: add root-alias shim and cache/docs updates

(cherry picked from commit 802b9f6b191078f4168c689370be4c319bab8b80)

* fix: resolve type errors from cherry-pick conflict resolution

- Rebrand remaining discoverOpenClawPlugins → discoverRemoteClawPlugins
  refs in discovery.test.ts (outside conflict zone, missed by auto-merge)
- Remove gutted memory-slot fast-path block in loader.ts that referenced
  resolveMemorySlotDecision/memorySlot/selectedMemoryPluginId

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Gustavo Madeira Santana <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>

* Cherry-pick 7a2f5a009: Plugin SDK: add full bundled subpath wiring (#1688)

* Plugin SDK: add full bundled subpath wiring

(cherry picked from commit 7a2f5a0098d192944825f17d3be457af91d2bed1)

* fix: remove gutted memory-core/memory-lancedb from build configs

Remove memory-core and memory-lancedb entries from tsdown, tsconfig,
package.json exports, release-check, and check-plugin-sdk-exports —
these plugin-sdk files were deleted as part of gutted memory subsystem.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Gustavo Madeira Santana <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>

* fix(daemon): handle systemctl is-enabled exit 4 (not-found) on Ubuntu (#33634) (#1689)

Merged via squash.

Prepared head SHA: 67dffc3ee239cd7b813cb200c3dd5475d9e203a6
Co-authored-by: Yuandiaodiaodiao <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

(cherry picked from commit 4fb40497d4b64dffa511562db11b94279704a4c3)

Co-authored-by: a <[email protected]>

* Cherry-pick c8ebd48e0: fix(node-host): sync rawCommand with hardened argv after executable path pinning (#33137) (#1690)

* fix(node-host): sync rawCommand with hardened argv after executable path pinning (#33137)

Merged via squash.

Prepared head SHA: a7987905f7ad6cf5fee286ffa81ceaad8297174f
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

(cherry picked from commit c8ebd48e0f4c110615981cc1485d4cb40374b825)

* fix(node-host): adapt rawCommand test for fork's path-pinning scope

Fork's isPathLikeExecutableToken does not resolve bare PATH commands
like "poccmd" — only path-like tokens (./foo, /usr/bin/foo).  Adjust
test expectation to match fork behavior: argv stays unchanged, so
rawCommand matches the original command text.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Sid <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>

* Cherry-pick a95a0be13: feat(slack): add typingReaction config for DM typing indicator fallback (#19816) (#1691)

* feat(slack): add typingReaction config for DM typing indicator fallback (#19816)

* feat(slack): add typingReaction config for DM typing indicator fallback

Adds a reaction-based typing indicator for Slack DMs that works without
assistant mode. When `channels.slack.typingReaction` is set (e.g.
"hourglass_flowing_sand"), the emoji is added to the user's message when
processing starts and removed when the reply is sent.

Addresses #19809

* test(slack): add typingReaction to createSlackMonitorContext test callers

* test(slack): add typingReaction to test context callers

* test(slack): add typingReaction to context fixture

* docs(changelog): credit Slack typingReaction feature

* test(slack): align existing-thread history expectation

---------

Co-authored-by: Vincent Koc <[email protected]>
(cherry picked from commit a95a0be133982999f31ccd4c05dc582fc4bacb3f)

* fix(slack): use RemoteClawConfig in prepare test — upstream used OpenClawConfig

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

---------

Co-authored-by: Dale Yarborough <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>

* fix(slack): route system events to bound agent sessions (#34045) (#1692)

* fix(slack): route system events via binding-aware session keys

* fix(slack): pass sender to system event session resolver

* fix(slack): include sender context for interaction session routing

* fix(slack): include modal submitter in session routing

* test(slack): cover binding-aware system event routing

* test(slack): update interaction session key assertions

* test(slack): assert reaction session routing carries sender

* docs(changelog): note slack system event routing fix

* Update CHANGELOG.md

(cherry picked from commit c1bb07bd165f636744d9d7ed9d351d96c7fe89c4)

Co-authored-by: Vincent Koc <[email protected]>

* feat(ios): add Live Activity connection status + stale cleanup (#33591) (#1693)

* feat(ios): add live activity connection status and cleanup

Add lock-screen/Dynamic Island connection health states and prune duplicate/stale activities before reuse. This intentionally excludes AI/title generation and heavier UX rewrites from #27488.



* fix(ios): treat ended live activities as inactive

* chore(changelog): add PR reference and author thanks

---------


(cherry picked from commit bd25182d5a9f04114873c5f5eb3d310bbf48938e)

Co-authored-by: Mariano <[email protected]>
Co-authored-by: leepokai <[email protected]>

* fix(agents): detect Venice provider proxying xAI/Grok models for schema cleaning (#35355)

Merged via squash.

Prepared head SHA: 8bfdec257bb6a6025cb69a0a213a433da32b15db
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

(cherry picked from commit 987e47336484c0004f5147ec184e05a5991e3260)

* fix(subagents): strip leaked [[reply_to]] tags from completion announces (#34503)

* fix(subagents): strip reply tags from completion delivery text

* test(subagents): cover reply-tag stripping in cron completion sends

* changelog: note iMessage reply-tag stripping in completion announces

* Update CHANGELOG.md

* Apply suggestion from @greptile-apps[bot]

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
(cherry picked from commit 4dc0c66399e107cb089e090e745679da216ff105)

* fix(agents): set preserveSignatures to isAnthropic in resolveTranscriptPolicy (#32813)

Merged via squash.

Prepared head SHA: f522d21ca59a42abac554435a0aa646f6a34698d
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

(cherry picked from commit 591264ef52040b5cc80582d9481a9323d0dedb49)

* fix(routing): avoid full binding rescans in resolveAgentRoute (#36915)

(cherry picked from commit c260e207b299fc8bac45558f19215622108961a6)

* fix(secrets): harden api key normalization for ByteString headers

(cherry picked from commit 1ab9393212b2256f3b3e257e567e49755309a293)

* fix(browser): remove deprecated --disable-blink-features=AutomationControlled flag

- Removes OpenClaw's default `--disable-blink-features=AutomationControlled` Chrome launch switch to avoid unsupported-flag warnings in newer Chrome (#35721).
- Preserves compatibility for older Chrome via `browser.extraArgs` override behavior (source analysis: #35770, #35728, #35727, #35885).
- Synthesis attribution: thanks @Sid-Qin, @kevinWangSheng, @ningding97, @Naylenv, @clawbie.

Source PR refs: #35734, #35770, #35728, #35727, #35885

Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: kevinWangSheng <[email protected]>
Co-authored-by: ningding97 <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: clawbie <[email protected]>
Co-authored-by: Takhoffman <[email protected]>
(cherry picked from commit 8d48235d3a655b16feadcbe4552b87978c1bebfc)

* refactor(agents): share failover HTTP status classification (#36615)

(cherry picked from commit f014e255df)

* test(agents): add provider-backed failover regressions (#36735)

(cherry picked from commit 6859619e98)

* fix(agents): classify insufficient_quota 400s as billing (#36783)

(cherry picked from commit 49acb07f9f)

* fix(agents): update pi-embedded-helpers import to agent-helpers in transcript-policy

Fixes import path from cherry-picked 591264ef5 to match fork's renamed
agent-helpers module.

* fix: resolve build errors from cherry-picks

- Fix transcript-policy import: model-selection.js → provider-utils.js
- Fix remaining OpenClawConfig → RemoteClawConfig in resolve-route
- Add auth_permanent to FailoverReason type
- Add isAuthPermanentErrorMessage function and authPermanent error patterns
- Remove orphaned test files (model-fallback.test.ts,
  minimax-vlm.normalizes-api-key.test.ts) that depend on modules
  not present in fork

* fix(review): enforce behavioral sweep validation

(cherry picked from commit 4cc293d084286e5570d8bfb2d67e22d6f14354f1)

* fix: add spanish locale support (#35038) (thanks @DaoPromociones)

(cherry picked from commit ed05810d68b96e392a0ccfe76f6d4ae0ea09866a)

* fix(deps): patch hono transitive audit vulnerabilities

(cherry picked from commit 809f9513acf0c4d8670164a1485834f959f484d9)

* fix(deps): bump tar to 7.5.10

(cherry picked from commit 4d06c909d2fb61b4b1501d927a2c6816e9920ef6)

* docs(changelog): document dependency security fixes

(cherry picked from commit 498948581a673b1fe13d18c42ab3882b90819796)

* fix(pr): make review claim step required

(cherry picked from commit 5d5fa0dac8d378a493c85baa9f8fdbb4d42f89f2)

* chore(changelog): add dedupe note openclaw#27521 thanks @shivama205

(cherry picked from commit 1805735c639c1d61522f5c8ad8cade99837a0ace)

* chore(pr): enforce changelog placement and reduce merge sync churn

(cherry picked from commit 60849f33357882e00722216cc1a555f12337ac78)

* fix(memory): avoid destructive qmd collection rebinds

(cherry picked from commit f771ba8de9)

[partial: memory subsystem files discarded — FORK_DELETED; changelog entry kept]

* Docs: clarify OpenAI-compatible TTS endpoints

(cherry picked from commit 6b2c1151678816b6a367eaa344cb05895ab38d7c)

* Docs: document Control UI locale support

(cherry picked from commit 2b45eb0e52e254fb78f6addd476f4fac36d8093f)

* fix: regenerate pnpm-lock.yaml for fork dependency tree

* fix(feishu): comprehensive reply mechanism — outbound replyToId forwarding + topic-aware reply targeting (#33789)

* fix(feishu): comprehensive reply mechanism fix — outbound replyToId forwarding + topic-aware reply targeting

- Forward replyToId from ChannelOutboundContext through sendText/sendMedia
  to sendMessageFeishu/sendMarkdownCardFeishu/sendMediaFeishu, enabling
  reply-to-message via the message tool.

- Fix group reply targeting: use ctx.messageId (triggering message) in
  normal groups to prevent silent topic thread creation (#32980). Preserve
  ctx.rootId targeting for topic-mode groups (group_topic/group_topic_sender)
  and groups with explicit replyInThread config.

- Add regression tests for both fixes.

Fixes #32980
Fixes #32958
Related #19784

* fix: normalize Feishu delivery.to before comparing with messaging tool targets

- Add normalizeDeliveryTarget helper to strip user:/chat: prefixes for Feishu
- Apply normalization in matchesMessagingToolDeliveryTarget before comparison
- This ensures cron duplicate suppression works when session uses prefixed targets
  (user:ou_xxx) but messaging tool extract uses normalized bare IDs (ou_xxx)

Fixes review comment on PR #32755

(cherry picked from commit fc20106f16ccc88a5f02e58922bb7b7999fe9dcd)

* fix(feishu): catch thrown SDK errors for withdrawn reply targets

The Feishu Lark SDK can throw exceptions (SDK errors with .code or
AxiosErrors with .response.data.code) for withdrawn/deleted reply
targets, in addition to returning error codes in the response object.

Wrap reply calls in sendMessageFeishu and sendCardFeishu with
try-catch to handle thrown withdrawn/not-found errors (230011,
231003) and fall back to client.im.message.create, matching the
existing response-level fallback behavior.

Also extract sendFallbackDirect helper to deduplicate the
direct-send fallback block across both functions.

Closes #33496

(cherry picked from commit ad0901aec103a2c52f186686cfaf5f8ba54b4a48)

* feishu: forward outbound reply target context

(cherry picked from commit c129a691fcf552a1cebe1e8a22ea8611ffc3b377)

* feishu extension: tighten reply target fallback semantics

(cherry picked from commit f85ec610f267020b66713c09e648ec004b2e26f1)

* fix(feishu): align synthesized fallback typing and changelog attribution

* test(feishu): cover group_topic_sender reply targeting

---------

Co-authored-by: Xu Zimo <[email protected]>
Co-authored-by: Munem Hashmi <[email protected]>
Co-authored-by: bmendonca3 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 63ce7c74bdc08f264e636d13923c7cfc16c3110b)

* fix(feishu): use msg_type media for mp4 video (fixes #33674) (#33720)

* fix(feishu): use msg_type media for mp4 video (fixes #33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw/openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 68e68bfb57fa77893fd631d59b8c52f23087b2bf)

* Feishu: harden streaming merge semantics and final reply dedupe (#33245)

* Feishu: close duplicate final gap and cover routing precedence

* Feishu: resolve reviewer duplicate-final and routing feedback

* Feishu: tighten streaming send-mode option typing

* Feishu: fix reverse-overlap streaming merge ordering

* Feishu: align streaming final dedupe test expectation

* Feishu: allow distinct streaming finals while deduping repeats

---------

Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 3bf6ed181e03ed150f762cf7628075e452038a83)

* fix(feishu): check response.ok before calling response.json() in streaming card (#35628)

Merged via squash.

Prepared head SHA: 62c3fec80d97cea9be344c0bef5358a0a5dc5560
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

(cherry picked from commit 06ff25cce4d68b3398469bc07efc808d1be1103b)

* fix(feishu): add HTTP timeout to prevent per-chat queue deadlocks (#36430)

When the Feishu API hangs or responds slowly, the sendChain never settles,
causing the per-chat queue to remain in a processing state forever and
blocking all subsequent messages in that thread. This adds a 30-second
default timeout to all Feishu HTTP requests by providing a timeout-aware
httpInstance to the Lark SDK client.

Closes #36412

Co-authored-by: Ayane <[email protected]>
(cherry picked from commit ba223c776634963d5226c1f901487685e93859f7)

* fix(feishu): use probed botName for mention checks (#36391)

(cherry picked from commit b9f3f8d737f11c0f5bab0360b09af68fc38a2858)

* Feishu: honor bot mentions by ID despite aliases (Fixes #36317) (#36333)

(cherry picked from commit 627b37e34fc94660b35710a603f140481d95ded5)

* fix(feishu): accept groupPolicy "allowall" as alias for "open" (#36358)

* fix(feishu): accept groupPolicy "allowall" as alias for "open"

When users configure groupPolicy: "allowall" in Feishu channel config,
the Zod schema rejects the value and the runtime policy check falls
through to the allowlist path.  With an empty allowFrom array, all group
messages are silently dropped despite the intended "allow all" semantics.

Accept "allowall" at the schema level (transform to "open") and add a
runtime guard in isFeishuGroupAllowed so the value is handled even if it
bypasses schema validation.

Closes #36312

Made-with: Cursor

* Feishu: tighten allowall alias handling and coverage

---------

Co-authored-by: Tak Hoffman <[email protected]>
(cherry picked from commit 2972d6fa7929c293f4b62a606cd1dcb700ef5da7)

* synthesis: fix Feishu group mention slash parsing

## Summary\n\nFeishu group slash command parsing is fixed for mentions and command probes across authorization paths.\n\nThis includes:\n- Normalizing bot mention text in group context for reliable slash detection in message parsing.\n- Adding command-probe normalization for group slash invocations.\n\nCo-authored-by: Sid Qin <[email protected]>\nCo-authored-by: Tak Hoffman <[email protected]>

(cherry picked from commit 995ae73d5f4e14568d059ed80d614a34daef28bf)

* Feishu: normalize group slash command probing

- Feishu/group slash command detection: normalize group mention wrappers before command-authorization probing so mention-prefixed commands are recognized in group routing.\n- Source PR: #36011\n- Contributor: @liuxiaopai-ai\n\nCo-authored-by: Tak Hoffman <[email protected]>\nCo-authored-by: liuxiaopai-ai <[email protected]>

(cherry picked from commit 174eeea76ce2ee34744a2fc57e093811313affb3)

* fix(feishu): avoid media regressions from global HTTP timeout (#36500)

* fix(feishu): avoid media regressions from global http timeout

* fix(feishu): source HTTP timeout from config

* fix(feishu): apply media timeout override to image uploads

* fix(feishu): invalidate cached client when timeout changes

* fix(feishu): clamp timeout values and cover image download

(cherry picked from commit bc66a8fa81a862258c875c1cc1c9371c72f4008e)

* Gateway: add SecretRef support for gateway.auth.token with auth-mode guardrails (#35094)

(cherry picked from commit 72cf9253fc)

[AUTO-PARTIAL] Discarded gutted src/secrets/ layer files and files
depending on gutted secrets module (resolve-configured-secret-input-string,
doctor-gateway-auth-token, gateway-install-token, secretref test).
Kept gateway config types, schema, auth-mode-policy, and doc changes.

* Revert "Gateway: add SecretRef support for gateway.auth.token with auth-mode guardrails (#35094)"

This reverts commit c364ee962de6a27cbbc346211631d119f91f54a0.

* fix(feishu): add missing sendMarkdownCardFeishu import in outbound

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(feishu): type-cast timeout option for SDK compatibility

The Feishu SDK type definitions don't include timeout in method option
types, but the runtime accepts it. Use spread with as-any cast to
preserve the timeout while satisfying the type checker.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* fix(embedded): classify model_context_window_exceeded as context overflow, trigger compaction (#35934)

Merged via squash.

Prepared head SHA: 4301a03e48e6e6b2f5870e8a1305b3b9f45e32a3
Co-authored-by: Kai <[email protected]>
Co-authored-by: RealKai42 <[email protected]>
Reviewed-by: @gumadeiras

(cherry picked from commit 60a6d11116d7e8f0412157dff3e1e967e7e1e6e0)

* Compaction/Safeguard: add summary quality audit retries (#25556)

Merged via squash.

Prepared head SHA: ae29f39cd6e103f34e47b4f5ee5b9f12f06b1076
Co-authored-by: Rodrigo Uroz <[email protected]>
Co-authored-by: dra11y <[email protected]>
Reviewed-by: @gumadeiras

(cherry picked from commit 036c329716f69e06e14bda12e0e39b27a7b7e285)

* fix(config): prevent RangeError in merged schema cache key generation

Fix merged schema cache key generation for high-cardinality plugin/channel metadata by hashing incrementally instead of serializing one large aggregate string.

Includes changelog entry for the user-visible regression fix.

Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: Bill <[email protected]>
(cherry picked from commit a0b731e2ce1f75e964ee5c55e5fd919186c9f562)

* plugins: enforce prompt hook policy with runtime validation (#36567)

Merged via squash.

Prepared head SHA: 6b9d883b6ae33628235fb02ce39c0d0f46a065bb
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

(cherry picked from commit 688b72e1581024769351f8b39b1097e65c630440)

* fix: restore hook types and runners for prompt hook policy enforcement

Commit 688b72e15 (prompt hook policy) requires before_model_resolve,
before_prompt_build, and before_agent_start hooks to be registrable
so the per-plugin allowPromptInjection policy can filter them.

- Add missing entries to PluginHookHandlerMap for restored hook types
- Add merge functions and runner stubs for model/prompt/agent hooks
- Remove model/prompt/agent hooks from DEAD_HOOKS (policy handles them)
- Add PluginHookName entries for all upstream hook names
- Add PLUGIN_HOOK_NAMES entries for fork-specific runtime hooks

* fix: update dead-hooks test to match reduced DEAD_HOOKS set

before_model_resolve, before_prompt_build, before_agent_start were
removed from DEAD_HOOKS to enable prompt hook policy enforcement.

---------

Signed-off-by: HCL <[email protected]>
Co-authored-by: Mariano <[email protected]>
Co-authored-by: dorukardahan <[email protected]>
Co-authored-by: 13otKmdr <[email protected]>
Co-authored-by: Clawdoo <[email protected]>
Co-authored-by: Cui Chen <[email protected]>
Co-authored-by: habakan <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Co-authored-by: Viz <[email protected]>
Co-authored-by: Liu Xiaopai <[email protected]>
Co-authored-by: Nimrod Gutman <[email protected]>
Co-authored-by: Sid <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: Glucksberg <[email protected]>
Co-authored-by: Efe Büken <[email protected]>
Co-authored-by: Riccardo Marino <[email protected]>
Co-authored-by: HCL <[email protected]>
Co-authored-by: chengzhichao-xydt <[email protected]>
Co-authored-by: Altay <[email protected]>
Co-authored-by: wan.xi <[email protected]>
Co-authored-by: Shadow <[email protected]>
Co-authored-by: Mylszd <[email protected]>
Co-authored-by: Shadow <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
Co-authored-by: Gustavo Madeira Santana <[email protected]>
Co-authored-by: bmendonca3 <[email protected]>
Co-authored-by: Robin Waslander <[email protected]>
Co-authored-by: joshavant <[email protected]>
Co-authored-by: Eugene <[email protected]>
Co-authored-by: sircrumpet <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: Isis Anisoptera <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
Co-authored-by: Kesku <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: Lynn <[email protected]>
Co-authored-by: Bob <[email protected]>
Co-authored-by: Shakker <[email protected]>
Co-authored-by: Evgeny Zislis <[email protected]>
Co-authored-by: a <[email protected]>
Co-authored-by: Dale Yarborough <[email protected]>
Co-authored-by: leepokai <[email protected]>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Vignesh Natarajan <[email protected]>
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: kevinWangSheng <[email protected]>
Co-authored-by: ningding97 <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: clawbie <[email protected]>
Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Darshil <[email protected]>
Co-authored-by: Madoka <[email protected]>
Co-authored-by: Xu Zimo <[email protected]>
Co-authored-by: Munem Hashmi <[email protected]>
Co-authored-by: Nhj <[email protected]>
Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: rexl2018 <[email protected]>
Co-authored-by: Ayane <[email protected]>
Co-authored-by: Ayane <[email protected]>
Co-authored-by: StingNing <[email protected]>
Co-authored-by: Kai <[email protected]>
Co-authored-by: Rodrigo Uroz <[email protected]>
Co-authored-by: Bill <[email protected]>
lukeg826 pushed a commit to lukeg826/openclaw that referenced this pull request Mar 26, 2026
…penclaw#33720)

* fix(feishu): use msg_type media for mp4 video (fixes openclaw#33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
0x666c6f added a commit to 0x666c6f/openclaw that referenced this pull request Mar 26, 2026
…nclaw#29)

* Plugins/llm-task: migrate to scoped plugin-sdk imports

* Plugins/lobster: migrate to scoped plugin-sdk imports

* Plugins/matrix: migrate to scoped plugin-sdk imports

* Plugins/mattermost: migrate to scoped plugin-sdk imports

* Plugins/memory-core: migrate to scoped plugin-sdk imports

* Plugins/memory-lancedb: migrate to scoped plugin-sdk imports

* Plugins/minimax-portal-auth: migrate to scoped plugin-sdk imports

* Plugins/msteams: migrate to scoped plugin-sdk imports

* Plugins/nextcloud-talk: migrate to scoped plugin-sdk imports

* Plugins/nostr: migrate to scoped plugin-sdk imports

* Plugins/open-prose: migrate to scoped plugin-sdk imports

* Plugins/phone-control: migrate to scoped plugin-sdk imports

* Plugins/qwen-portal-auth: migrate to scoped plugin-sdk imports

* Plugins/synology-chat: migrate to scoped plugin-sdk imports

* Plugins/talk-voice: migrate to scoped plugin-sdk imports

* Plugins/test-utils: migrate to scoped plugin-sdk imports

* Plugins/thread-ownership: migrate to scoped plugin-sdk imports

* Plugins/tlon: migrate to scoped plugin-sdk imports

* Plugins/twitch: migrate to scoped plugin-sdk imports

* Plugins/voice-call: migrate to scoped plugin-sdk imports

* Plugins/whatsapp: migrate to scoped plugin-sdk imports

* Plugins/zalo: migrate to scoped plugin-sdk imports

* Plugins/zalouser: migrate to scoped plugin-sdk imports

* Chore: remove accidental .DS_Store artifact

* chore(docs): add plugins refactor changelog entry

* feat(ios): add Live Activity connection status + stale cleanup (#33591)

* feat(ios): add live activity connection status and cleanup

Add lock-screen/Dynamic Island connection health states and prune duplicate/stale activities before reuse. This intentionally excludes AI/title generation and heavier UX rewrites from #27488.

Co-authored-by: leepokai <[email protected]>

* fix(ios): treat ended live activities as inactive

* chore(changelog): add PR reference and author thanks

---------

Co-authored-by: leepokai <[email protected]>

* fix: kill stuck ACP child processes on startup and harden sessions in discord threads (#33699)

* Gateway: resolve agent.wait for chat.send runs

* Discord: harden ACP thread binding + listener timeout

* ACPX: handle already-exited child wait

* Gateway/Discord: address PR review findings

* Discord: keep ACP error-state thread bindings on startup

* gateway: make agent.wait dedupe bridge event-driven

* discord: harden ACP probe classification and cap startup fan-out

* discord: add cooperative timeout cancellation

* discord: fix startup probe concurrency helper typing

* plugin-sdk: avoid Windows root-alias shard timeout

* plugin-sdk: keep root alias reflection path non-blocking

* discord+gateway: resolve remaining PR review findings

* gateway+discord: fix codex review regressions

* Discord/Gateway: address Codex review findings

* Gateway: keep agent.wait lifecycle active with shared run IDs

* Discord: clean up status reactions on aborted runs

* fix: add changelog note for ACP/Discord startup hardening (#33699) (thanks @dutifulbob)

---------

Co-authored-by: Onur <[email protected]>

* fix: relay ACP sessions_spawn parent streaming (#34310) (thanks @vincentkoc) (#34310)

Co-authored-by: Onur Solmaz <[email protected]>

* fix(telegram): materialize dm draft final to avoid duplicates

* docs(changelog): credit @Brotherinlaw-13 for #34318

* fix: prevent nodes media base64 context bloat (#34332)

* fix: preserve raw media invoke for HTTP tool clients (#34365)

* fix(slack): route system events to bound agent sessions (#34045)

* fix(slack): route system events via binding-aware session keys

* fix(slack): pass sender to system event session resolver

* fix(slack): include sender context for interaction session routing

* fix(slack): include modal submitter in session routing

* test(slack): cover binding-aware system event routing

* test(slack): update interaction session key assertions

* test(slack): assert reaction session routing carries sender

* docs(changelog): note slack system event routing fix

* Update CHANGELOG.md

* Delete changelog/fragments directory

* fix(memory): serialize local embedding initialization to avoid duplicate model loads (#15639)

Merged via squash.

Prepared head SHA: a085fc21a8ba7163fffdb5de640dd4dc1ff5a88e
Co-authored-by: SubtleSpark <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(model): propagate custom provider headers to model objects (#27490)

Merged via squash.

Prepared head SHA: e4183b398fc7eb4c18b2b691cb0dd882ec993608
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(daemon): handle systemctl is-enabled exit 4 (not-found) on Ubuntu (#33634)

Merged via squash.

Prepared head SHA: 67dffc3ee239cd7b813cb200c3dd5475d9e203a6
Co-authored-by: Yuandiaodiaodiao <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(node-host): sync rawCommand with hardened argv after executable path pinning (#33137)

Merged via squash.

Prepared head SHA: a7987905f7ad6cf5fee286ffa81ceaad8297174f
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* Agents: add generic poll-vote action support

* fix(ollama): pass provider headers to Ollama stream function (#24285)

createOllamaStreamFn() only accepted baseUrl, ignoring custom headers
configured in models.providers.<provider>.headers. This caused 403
errors when Ollama endpoints are behind reverse proxies that require
auth headers (e.g. X-OLLAMA-KEY via HAProxy).

Add optional defaultHeaders parameter to createOllamaStreamFn() and
merge them into every fetch request. Provider headers from config are
now passed through at the call site in the embedded runner.

Fixes #24285

* test(ollama): add default header precedence coverage

* chore(changelog): add PR entry openclaw#24337 thanks @echoVic

* Outbound: allow text-only plugin adapters

* Outbound: avoid empty multi-media fallback sends

* chore(changelog): align outbound adapter entry openclaw#32788 thanks @liuxiaopai-ai

* fix(outbound): fail media-only text-only adapter fallback

* chore(changelog): clarify outbound media-only fallback openclaw#32788 thanks @liuxiaopai-ai

* fix(review): enforce behavioral sweep validation

* Fix gateway restart false timeouts on Debian/systemd (#34874)

* daemon(systemd): target sudo caller user scope

* test(systemd): cover sudo user scope commands

* infra(ports): fall back to ss when lsof missing

* test(ports): verify ss fallback listener detection

* cli(gateway): use probe fallback for restart health

* test(gateway): cover restart-health probe fallback

* Compaction/Safeguard: require structured summary headings (#25555)

Merged via squash.

Prepared head SHA: 0b1df34806a7b788261290be55760fd89220de53
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Fix Linux daemon install checks when systemd user bus env is missing (#34884)

* daemon(systemd): fall back to machine user scope when user bus is missing

* test(systemd): cover machine scope fallback for user-bus errors

* test(systemd): reset execFile mock state across cases

* test(systemd): make machine-user fallback assertion portable

* fix(daemon): keep root sudo path on direct user scope

* test(systemd): cover sudo root user-scope behavior

* ci: use resolvable bun version in setup-node-env

* agents: preserve totalTokens on request failure instead of using contextWindow (#34275)

Merged via squash.

Prepared head SHA: f9d111d0a79a07815d476356e98a28df3a0000ba
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix: align AGENTS.md template section names with post-compaction extraction (#25029) (#25098)

Merged via squash.

Prepared head SHA: 8cd6cc8049aab5a94d8a9d5fb08f2e792c4ac5fd
Co-authored-by: echoVic <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Changelog: add daemon systemd user-bus fallback entry (#34884)

* Changelog: add gateway restart health entry (#34874)

* fix: finalize spanish locale support

* fix: add spanish locale support (#35038) (thanks @DaoPromociones)

* fix(deps): patch hono transitive audit vulnerabilities

* fix(security): avoid prototype-chain account path checks (#34982)

Merged via squash.

Prepared head SHA: f89cc6a649959997fe1dec1e1c1bff9a61b2de98
Co-authored-by: HOYALIM <[email protected]>
Co-authored-by: dvrshil <[email protected]>
Reviewed-by: @dvrshil

* fix(deps): bump tar to 7.5.10

* docs(changelog): document dependency security fixes

* fix: restore auto-reply system events timeline (#34794) (thanks @anisoptera) (#34794)

Co-authored-by: Ayaan Zaidi <[email protected]>

* fix(feishu): comprehensive reply mechanism — outbound replyToId forwarding + topic-aware reply targeting (#33789)

* fix(feishu): comprehensive reply mechanism fix — outbound replyToId forwarding + topic-aware reply targeting

- Forward replyToId from ChannelOutboundContext through sendText/sendMedia
  to sendMessageFeishu/sendMarkdownCardFeishu/sendMediaFeishu, enabling
  reply-to-message via the message tool.

- Fix group reply targeting: use ctx.messageId (triggering message) in
  normal groups to prevent silent topic thread creation (#32980). Preserve
  ctx.rootId targeting for topic-mode groups (group_topic/group_topic_sender)
  and groups with explicit replyInThread config.

- Add regression tests for both fixes.

Fixes #32980
Fixes #32958
Related #19784

* fix: normalize Feishu delivery.to before comparing with messaging tool targets

- Add normalizeDeliveryTarget helper to strip user:/chat: prefixes for Feishu
- Apply normalization in matchesMessagingToolDeliveryTarget before comparison
- This ensures cron duplicate suppression works when session uses prefixed targets
  (user:ou_xxx) but messaging tool extract uses normalized bare IDs (ou_xxx)

Fixes review comment on PR #32755

(cherry picked from commit fc20106f16ccc88a5f02e58922bb7b7999fe9dcd)

* fix(feishu): catch thrown SDK errors for withdrawn reply targets

The Feishu Lark SDK can throw exceptions (SDK errors with .code or
AxiosErrors with .response.data.code) for withdrawn/deleted reply
targets, in addition to returning error codes in the response object.

Wrap reply calls in sendMessageFeishu and sendCardFeishu with
try-catch to handle thrown withdrawn/not-found errors (230011,
231003) and fall back to client.im.message.create, matching the
existing response-level fallback behavior.

Also extract sendFallbackDirect helper to deduplicate the
direct-send fallback block across both functions.

Closes #33496

(cherry picked from commit ad0901aec103a2c52f186686cfaf5f8ba54b4a48)

* feishu: forward outbound reply target context

(cherry picked from commit c129a691fcf552a1cebe1e8a22ea8611ffc3b377)

* feishu extension: tighten reply target fallback semantics

(cherry picked from commit f85ec610f267020b66713c09e648ec004b2e26f1)

* fix(feishu): align synthesized fallback typing and changelog attribution

* test(feishu): cover group_topic_sender reply targeting

---------

Co-authored-by: Xu Zimo <[email protected]>
Co-authored-by: Munem Hashmi <[email protected]>
Co-authored-by: bmendonca3 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(feishu): use msg_type media for mp4 video (fixes #33674) (#33720)

* fix(feishu): use msg_type media for mp4 video (fixes #33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw/openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(agents): bypass pendingDescendantRuns guard for cron announce delivery (#35185)

* fix(agents): bypass pendingDescendantRuns guard for cron announce delivery

Standalone cron job completions were blocked from direct channel delivery
when the cron run had spawned subagents that were still registered as
pending. The pendingDescendantRuns guard exists for live orchestration
coordination and should not apply to fire-and-forget cron announce sends.

Thread the announceType through the delivery chain and skip both the
child-descendant and requester-descendant pending-run guards when the
announce originates from a cron job.

Closes #34966

* fix: ensure outbound session entry for cron announce with named agents (#32432)

Named agents may not have a session entry for their delivery target,
causing the announce flow to silently fail (delivered=false, no error).

Two fixes:
1. Call ensureOutboundSessionEntry when resolving the cron announce
   session key so downstream delivery can find channel metadata.
2. Fall back to direct outbound delivery when announce delivery fails
   to ensure cron output reaches the target channel.

Closes #32432

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: guard announce direct-delivery fallback against suppression leaks (#32432)

The `!delivered` fallback condition was too broad — it caught intentional
suppressions (active subagents, interim messages, SILENT_REPLY_TOKEN) in
addition to actual announce delivery failures.  Add an
`announceDeliveryWasAttempted` flag so the direct-delivery fallback only
fires when `runSubagentAnnounceFlow` was actually called and failed.

Also remove the redundant `if (route)` guard in
`resolveCronAnnounceSessionKey` since `resolved` being truthy guarantees
`route` is non-null.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix(cron): harden announce synthesis follow-ups

---------

Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* Feishu: harden streaming merge semantics and final reply dedupe (#33245)

* Feishu: close duplicate final gap and cover routing precedence

* Feishu: resolve reviewer duplicate-final and routing feedback

* Feishu: tighten streaming send-mode option typing

* Feishu: fix reverse-overlap streaming merge ordering

* Feishu: align streaming final dedupe test expectation

* Feishu: allow distinct streaming finals while deduping repeats

---------

Co-authored-by: Tak Hoffman <[email protected]>

* fix: cron backup should preserve pre-edit snapshot (#35195) (#35234)

* fix(cron): avoid overwriting .bak during normalization

Fixes openclaw/openclaw#35195

* test(cron): preserve pre-edit bak snapshot in normalization path

---------

Co-authored-by: 0xsline <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(cron): stabilize restart catch-up replay semantics (#35351)

* Cron: stabilize restart catch-up replay semantics

* Cron: respect backoff in startup missed-run replay

* cron: narrow startup replay backoff guard (#35391)

* cron: unify stale-run recovery and preserve manual-run every anchors (#35363)

* cron: unify stale-run recovery and preserve manual every anchors

* cron: address unresolved review threads on recovery paths

* cron: remove duplicate timestamp helper after rebase

* refactor(telegram): remove unused webhook callback helper (#27816)

* fix(pr): make review claim step required

* fix(skills): deduplicate slash commands by skillName across all interfaces

Move skill-command deduplication by skillName from the Discord-only
`dedupeSkillCommandsForDiscord` into `listSkillCommandsForAgents` so
every interface (TUI, Slack, text) consistently sees a clean command
list without platform-specific workarounds.

When multiple agents share a skill with the same name the old code
emitted `github` + `github_2` and relied on Discord to collapse them.
Now `listSkillCommandsForAgents` returns only the first registration
per skillName, and the Discord-specific wrapper is removed.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* style: fix formatting in skill-commands.test.ts and provider.ts

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* style(skills): align formatting cleanup for dedupe changes

* chore(changelog): add dedupe note openclaw#27521 thanks @shivama205

* fix(agents): detect Venice provider proxying xAI/Grok models for schema cleaning (#35355)

Merged via squash.

Prepared head SHA: 8bfdec257bb6a6025cb69a0a213a433da32b15db
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(agents): decode HTML entities in xAI/Grok tool call arguments (#35276)

Merged via squash.

Prepared head SHA: c4445d2938898ded9c046614f9315dbda65ec573
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(agents): guard promoteThinkingTagsToBlocks against malformed content entries (#35143)

Merged via squash.

Prepared head SHA: 3971122f5fd27c66c8c9c5ce783f00e113b1f47b
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(web-ui): render Accounts schema node properly (#35380)

Co-authored-by: stakeswky <[email protected]>
Co-authored-by: liuxiaopai-ai <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(agents): guard context pruning against malformed thinking blocks (#35146)

Merged via squash.

Prepared head SHA: a196a565b1b8e806ffbf85172bcf1128796b45a2
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(gateway): prevent internal route leakage in chat.send

Synthesis of routing fixes from #35321, #34635, and #35356 for internal-client reply safety.

- Require explicit `deliver: true` before inheriting any external delivery route.
- Keep webchat/TUI/UI-origin traffic on internal routing by default.
- Allow configured-main session inheritance only for non-Webchat/UI clients, and honor `session.mainKey`.
- Add regression tests for UI no-inherit, configured-main CLI inherit, and deliver-flag behavior.

Co-authored-by: alexyyyander <[email protected]>
Co-authored-by: Octane0411 <[email protected]>
Co-authored-by: Linux2010 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(gateway): pass actual version to Control UI client instead of dev (#35230)

* fix(gateway): pass actual version to Control UI client instead of "dev"

The GatewayClient, CLI WS client, and browser Control UI all sent
"dev" as their clientVersion during handshake, making it impossible
to distinguish builds in gateway logs and health snapshots.

- GatewayClient and CLI WS client now use the resolved VERSION constant
- Control UI reads serverVersion from the bootstrap endpoint and
  forwards it when connecting
- Bootstrap contract extended with serverVersion field

Closes #35209

* Gateway: fix control-ui version version-reporting consistency

* Control UI: guard deferred bootstrap connect after disconnect

* fix(ui): accept same-origin http and relative gateway URLs for client version

---------

Co-authored-by: Tak Hoffman <[email protected]>

* chore(pr): enforce changelog placement and reduce merge sync churn

* TTS: add baseUrl support to OpenAI TTS config (#34321)

Merged via squash.

Prepared head SHA: e9a10cf81d2021cf81091dfa81e13ffdbb6a540a
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* ACP: add persistent Discord channel and Telegram topic bindings (#34873)

* docs: add ACP persistent binding experiment plan

* docs: align ACP persistent binding spec to channel-local config

* docs: scope Telegram ACP bindings to forum topics only

* docs: lock bound /new and /reset behavior to in-place ACP reset

* ACP: add persistent discord/telegram conversation bindings

* ACP: fix persistent binding reuse and discord thread parent context

* docs: document channel-specific persistent ACP bindings

* ACP: split persistent bindings and share conversation id helpers

* ACP: defer configured binding init until preflight passes

* ACP: fix discord thread parent fallback and explicit disable inheritance

* ACP: keep bound /new and /reset in-place

* ACP: honor configured bindings in native command flows

* ACP: avoid configured fallback after runtime bind failure

* docs: refine ACP bindings experiment config examples

* acp: cut over to typed top-level persistent bindings

* ACP bindings: harden reset recovery and native command auth

* Docs: add ACP bound command auth proposal

* Tests: normalize i18n registry zh-CN assertion encoding

* ACP bindings: address review findings for reset and fallback routing

* ACP reset: gate hooks on success and preserve /new arguments

* ACP bindings: fix auth and binding-priority review findings

* Telegram ACP: gate ensure on auth and accepted messages

* ACP bindings: fix session-key precedence and unavailable handling

* ACP reset/native commands: honor fallback targets and abort on bootstrap failure

* Config schema: validate ACP binding channel and Telegram topic IDs

* Discord ACP: apply configured DM bindings to native commands

* ACP reset tails: dispatch through ACP after command handling

* ACP tails/native reset auth: fix target dispatch and restore full auth

* ACP reset detection: fallback to active ACP keys for DM contexts

* Tests: type runTurn mock input in ACP dispatch test

* ACP: dedup binding route bootstrap and reset target resolution

* reply: align ACP reset hooks with bound session key

* docs: replace personal discord ids with placeholders

* fix: add changelog entry for ACP persistent bindings (#34873) (thanks @dutifulbob)

---------

Co-authored-by: Onur <[email protected]>

* docs(telegram): recommend allowlist for single-user DM policy (#34841)

* docs(telegram): recommend allowlist for single-user bots

* docs(telegram): condense single-user allowlist note

---------

Co-authored-by: echoVic <[email protected]>

* fix(feishu): check response.ok before calling response.json() in streaming card (#35628)

Merged via squash.

Prepared head SHA: 62c3fec80d97cea9be344c0bef5358a0a5dc5560
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Mattermost: honor onmessage mention override and add gating diagnostics tests (#27160)

Merged via squash.

Prepared head SHA: 6cefb1d5bf3d6dfcec36c1cee3f9ea887f10c890
Co-authored-by: turian <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* fix(subagents): strip leaked [[reply_to]] tags from completion announces (#34503)

* fix(subagents): strip reply tags from completion delivery text

* test(subagents): cover reply-tag stripping in cron completion sends

* changelog: note iMessage reply-tag stripping in completion announces

* Update CHANGELOG.md

* Apply suggestion from @greptile-apps[bot]

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix(cron): restore direct fallback after announce failure in best-effort mode (openclaw#36177)

Verified:
- pnpm build
- pnpm check (fails on pre-existing origin/main lint debt in extensions/mattermost imports)
- pnpm test:macmini

Co-authored-by: Tak Hoffman <[email protected]>

* test(cron): add cross-channel announce fallback regression coverage (openclaw#36197)

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check (fails on pre-existing origin/main lint debt in extensions/mattermost imports)
- pnpm test:macmini

Co-authored-by: Tak Hoffman <[email protected]>

* feat(mattermost): add interactive buttons support (#19957)

Merged via squash.

Prepared head SHA: 8a25e608729d0b9fd07bb0ee4219d199d9796dbe
Co-authored-by: tonydehnke <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* fix(browser): remove deprecated --disable-blink-features=AutomationControlled flag

- Removes OpenClaw's default `--disable-blink-features=AutomationControlled` Chrome launch switch to avoid unsupported-flag warnings in newer Chrome (#35721).
- Preserves compatibility for older Chrome via `browser.extraArgs` override behavior (source analysis: #35770, #35728, #35727, #35885).
- Synthesis attribution: thanks @Sid-Qin, @kevinWangSheng, @ningding97, @Naylenv, @clawbie.

Source PR refs: #35734, #35770, #35728, #35727, #35885

Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: kevinWangSheng <[email protected]>
Co-authored-by: ningding97 <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: clawbie <[email protected]>
Co-authored-by: Takhoffman <[email protected]>

* fix(feishu): add HTTP timeout to prevent per-chat queue deadlocks (#36430)

When the Feishu API hangs or responds slowly, the sendChain never settles,
causing the per-chat queue to remain in a processing state forever and
blocking all subsequent messages in that thread. This adds a 30-second
default timeout to all Feishu HTTP requests by providing a timeout-aware
httpInstance to the Lark SDK client.

Closes #36412

Co-authored-by: Ayane <[email protected]>

* fix(feishu): use probed botName for mention checks (#36391)

* Feishu: honor bot mentions by ID despite aliases (Fixes #36317) (#36333)

* Mattermost: switch plugin-sdk imports to scoped subpaths (openclaw#36480)

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(feishu): accept groupPolicy "allowall" as alias for "open" (#36358)

* fix(feishu): accept groupPolicy "allowall" as alias for "open"

When users configure groupPolicy: "allowall" in Feishu channel config,
the Zod schema rejects the value and the runtime policy check falls
through to the allowlist path.  With an empty allowFrom array, all group
messages are silently dropped despite the intended "allow all" semantics.

Accept "allowall" at the schema level (transform to "open") and add a
runtime guard in isFeishuGroupAllowed so the value is handled even if it
bypasses schema validation.

Closes #36312

Made-with: Cursor

* Feishu: tighten allowall alias handling and coverage

---------

Co-authored-by: Tak Hoffman <[email protected]>

* synthesis: fix Feishu group mention slash parsing

## Summary\n\nFeishu group slash command parsing is fixed for mentions and command probes across authorization paths.\n\nThis includes:\n- Normalizing bot mention text in group context for reliable slash detection in message parsing.\n- Adding command-probe normalization for group slash invocations.\n\nCo-authored-by: Sid Qin <[email protected]>\nCo-authored-by: Tak Hoffman <[email protected]>

* Feishu: normalize group slash command probing

- Feishu/group slash command detection: normalize group mention wrappers before command-authorization probing so mention-prefixed commands are recognized in group routing.\n- Source PR: #36011\n- Contributor: @liuxiaopai-ai\n\nCo-authored-by: Tak Hoffman <[email protected]>\nCo-authored-by: liuxiaopai-ai <[email protected]>

* add prependSystemContext and appendSystemContext to before_prompt_build (fixes #35131) (#35177)

Merged via squash.

Prepared head SHA: d9a2869ad69db9449336a2e2846bd9de0e647ac6
Co-authored-by: maweibin <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(feishu): avoid media regressions from global HTTP timeout (#36500)

* fix(feishu): avoid media regressions from global http timeout

* fix(feishu): source HTTP timeout from config

* fix(feishu): apply media timeout override to image uploads

* fix(feishu): invalidate cached client when timeout changes

* fix(feishu): clamp timeout values and cover image download

* Gateway: add SecretRef support for gateway.auth.token with auth-mode guardrails (#35094)

* fix(embedded): classify model_context_window_exceeded as context overflow, trigger compaction (#35934)

Merged via squash.

Prepared head SHA: 20fa77289c80b2807a6779a3df70440242bc18ca
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(agents): skip compaction API call when session has no real messages (#36451)

Merged via squash.

Prepared head SHA: 52dd6317895c7bd10855d2bd7dbbfc2f5279b68e
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(ui): catch marked.js parse errors to prevent Control UI crash (#36445)

- Prevent Control UI session render crashes when `marked.parse()` encounters pathological recursive markdown by safely falling back to escaped `<pre>` output.
- Tighten markdown fallback regression coverage and keep changelog attribution in sync for this crash-hardening path.

Co-authored-by: Bin Deng <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(session): archive old transcript on daily/scheduled reset to prevent orphaned files (#35493)

Merged via squash.

Prepared head SHA: 0d95549d752adecfc0b08d5cd55a8b8c75e264fe
Co-authored-by: byungsker <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(agents): set preserveSignatures to isAnthropic in resolveTranscriptPolicy (#32813)

Merged via squash.

Prepared head SHA: f522d21ca59a42abac554435a0aa646f6a34698d
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix: avoid false global rate-limit classification from generic cooldown text (#32972)

Merged via squash.

Prepared head SHA: 813c16f5afce415da130a917d9ce9f968912b477
Co-authored-by: stakeswky <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* refactor(agents): share failover HTTP status classification (#36615)

* fix(agents): classify transient failover statuses consistently

* fix(agents): preserve legacy failover status mapping

* fix(failover): narrow service-unavailable to require overload indicator (#32828) (#36646)

Merged via squash.

Prepared head SHA: 46fb4306127972d7635f371fd9029fbb9baff236
Co-authored-by: jnMetaCode <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* Compaction/Safeguard: add summary quality audit retries (#25556)

Merged via squash.

Prepared head SHA: be473efd1635616ebbae6e649d542ed50b4a827f
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* test(agents): add provider-backed failover regressions (#36735)

* test(agents): add provider-backed failover fixtures

* test(agents): cover more provider error docs

* test(agents): tighten provider doc fixtures

* Docs: add Slack typing reaction fallback

* Docs: update gateway config reference for Slack and TTS

* Docs: clarify OpenAI-compatible TTS endpoints

* Docs: document Control UI locale support

* Docs: cover heartbeat, cron, and plugin route updates

* fix(ui): bump dompurify to 3.3.2 (#36781)

* UI: bump dompurify to 3.3.2

* Deps: refresh dompurify lockfile

* UI: hoist lifecycle connect test mocks (#36788)

* fix(agents): classify insufficient_quota 400s as billing (#36783)

* feat: append UTC time alongside local time in shared Current time lines (#32423)

Merged via squash.

Prepared head SHA: 9e8ec13933b5317e7cff3f0bc048de515826c31a
Co-authored-by: jriff <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* fix(auth): grant senderIsOwner for internal channels with operator.admin scope (openclaw#35704)

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Naylenv <[email protected]>
Co-authored-by: Octane0411 <[email protected]>
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(config): prevent RangeError in merged schema cache key generation

Fix merged schema cache key generation for high-cardinality plugin/channel metadata by hashing incrementally instead of serializing one large aggregate string.

Includes changelog entry for the user-visible regression fix.

Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: Bill <[email protected]>

* fix(slack): propagate mediaLocalRoots through Slack send path

Restore Slack local file upload parity with CVE-era local media allowlist enforcement by threading `mediaLocalRoots` through the Slack send call chain.

- pass `ctx.mediaLocalRoots` from Slack channel action adapter into `handleSlackAction`
- add and forward `mediaLocalRoots` in Slack action context/send path
- pass `mediaLocalRoots` into `sendMessageSlack` for upload allowlist enforcement
- add changelog entry with attribution for this behavior fix

Co-authored-by: 2233admin <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(slack): preserve dedupe while recovering dropped app_mention (#34937)

This PR fixes Slack mention loss without reintroducing duplicate dispatches.

- Preserve seen-message dedupe at ingress to prevent duplicate processing.
- Allow a one-time app_mention retry only when the paired message event was previously dropped before dispatch.
- Add targeted race tests for both recovery and duplicate-prevention paths.

Co-authored-by: littleben <[email protected]>
Co-authored-by: OpenClaw Agent <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* README: add algal to contributors list (#2046)

* fix: decouple Discord inbound worker timeout from listener timeout (#36602) (thanks @dutifulbob) (#36602)

Co-authored-by: Onur Solmaz <[email protected]>

* plugins: enforce prompt hook policy with runtime validation (#36567)

Merged via squash.

Prepared head SHA: 6b9d883b6ae33628235fb02ce39c0d0f46a065bb
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(memory): avoid destructive qmd collection rebinds

* Harden Telegram poll gating and schema consistency (#36547)

Merged via squash.

Prepared head SHA: f77824419e3d166f727474a9953a063a2b4547f2
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(browser): close tracked tabs on session cleanup (#36666)

* Diffs: restore system prompt guidance (#36904)

Merged via squash.

Prepared head SHA: 1b3be3c87957c068473d5c86b9efba4a1a8503f2
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(routing): avoid full binding rescans in resolveAgentRoute (#36915)

* fix(gateway): honor insecure ws override for remote hostnames

* fix(llm-task): load runEmbeddedPiAgent from dist/extensionAPI in installs

* fix(auth): harden openai-codex oauth login path

* feat(telegram/acp): Topic Binding, Pin Binding Message, Fix Spawn Param Parsing (#36683)

* fix(acp): normalize unicode flags and Telegram topic binding

* feat(telegram/acp): restore topic-bound ACP and session bindings

* fix(acpx): clarify permission-denied guidance

* feat(telegram/acp): pin spawn bind notice in topics

* docs(telegram): document ACP topic thread binding behavior

* refactor(reply): share Telegram conversation-id resolver

* fix(telegram/acp): preserve bound session routing semantics

* fix(telegram): respect binding persistence and expiry reporting

* refactor(telegram): simplify binding lifecycle persistence

* fix(telegram): bind acp spawns in direct messages

* fix: document telegram ACP topic binding changelog (#36683) (thanks @huntharo)

---------

Co-authored-by: Onur <[email protected]>

* fix(gateway): preserve streamed prefixes across tool boundaries

* fix(tui): prevent stale model indicator after /model

* Memory: handle SecretRef keys in doctor embeddings (#36835)

Merged via squash.

Prepared head SHA: c1a3d0caae60115d886e8bfc9983c9533c773f04
Co-authored-by: joshavant <[email protected]>
Co-authored-by: joshavant <[email protected]>
Reviewed-by: @joshavant

* fix(openai-codex): request required oauth api scopes (#24720)

* fix(memory-flush): ban timestamped variant files in default flush prompt (#34951)

Merged via squash.

Prepared head SHA: efadda4988b460e6da07be72994d4951d64239d0
Co-authored-by: zerone0x <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(tui): render final event error when assistant output is empty (#14687)

* feat(agents): flush reply pipeline before compaction wait (#35489)

Merged via squash.

Prepared head SHA: 7dbbcc510b74b0e8d35eb750d24575e34b5d769a
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(secrets): harden api key normalization for ByteString headers

* fix(slack): remove double mrkdwn conversion in native streaming path

Remove redundant text normalization from Slack native streaming markdown_text flow so Markdown formatting is preserved.

Synthesis context: overlaps reviewed from #34931, #34759, #34716, #34682, #34814.

Co-authored-by: littleben <[email protected]>
Co-authored-by: dunamismax <[email protected]>
Co-authored-by: Octane <[email protected]>
Co-authored-by: Mitsuyuki Osabe <[email protected]>
Co-authored-by: Kai <[email protected]>
Co-authored-by: OpenClaw Agent <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(kimi-coding): normalize anthropic tool payload format

* fix(slack): thread channel ID through inbound context for reactions (#34831)

Slack reaction/thread context routing fixes via canonical synthesis of #34831.

Co-authored-by: Tak <[email protected]>

* fix(heartbeat): pin HEARTBEAT.md reads to workspace path

* fix(subagents): recover announce cleanup after kill/complete race

* feat(hooks): emit compaction lifecycle hooks (#16788)

* fix(auth): harden openai-codex oauth refresh fallback

* fix(subagents): announce delivery with descendant gating, frozen result refresh, and cron retry (#35080)

Thanks @tyler6204

* fix(agents): avoid synthetic tool-result writes on idle-timeout cleanup

* fix(agent): harden undici stream timeouts for long openai-completions runs

* fix(slack): record app_mention retry key before dedupe check (#37033)

- Prime app_mention retry allowance before dedupe so near-simultaneous message/app_mention races do not drop valid mentions.
- Prevent duplicate dispatch when app_mention wins the race and message prepare later succeeds.
- Prune dispatched mention keys and add regression coverage for both dropped and successful in-flight message outcomes.

Co-authored-by: Tak Hoffman <[email protected]>

* fix(agents): honor explicit rate-limit cooldown probes in fallback runs

* fix(agents): allow configured ollama endpoints without dummy api keys

* fix(memory): recover qmd updates from duplicate document constraints

* Doctor: warn on implicit heartbeat directPolicy (#36789)

* Changelog: note heartbeat directPolicy doctor warning

* Tests: cover heartbeat directPolicy doctor warning

* Doctor: warn on implicit heartbeat directPolicy

* Tests: cover per-agent heartbeat directPolicy warning

* Update CHANGELOG.md

* Plugins: clarify registerHttpHandler migration errors (#36794)

* Changelog: note plugin HTTP route migration diagnostics

* Tests: cover registerHttpHandler migration diagnostics

* Plugins: clarify registerHttpHandler migration errors

* Tests: cover registerHttpHandler diagnostic edge cases

* Plugins: tighten registerHttpHandler migration hint

* fix(memory): repair qmd collection name conflicts during ensure

* fix(memory): handle qmd search results without docid

* Plugins: avoid false integrity drift prompts on unpinned updates (#37179)

* Plugins: skip drift prompts for unpinned updates

* Plugins: cover unpinned integrity update behavior

* Changelog: add #37179 release note

* Delete changelog/fragments directory

* Update CHANGELOG.md

* fix(whatsapp): remove implicit [openclaw] self-chat prefix

* fix: remove config.schema from agent gateway tool (#7382)

Merged via squash.

Prepared head SHA: f34a7780690a941936b31899e2d096b8a07f4afc
Co-authored-by: kakuteki <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* feat(openai): add gpt-5.4 support for API and Codex OAuth (#36590)

* feat(openai): add gpt-5.4 support and priority processing

* feat(openai-codex): add gpt-5.4 oauth support

* fix(openai): preserve provider overrides in gpt-5.4 fallback

* fix(openai-codex): keep xhigh for gpt-5.4 default

* fix(models): preserve configured overrides in list output

* fix(models): close gpt-5.4 integration gaps

* fix(openai): scope service tier to public api

* fix(openai): complete prep followups for gpt-5.4 support (#36590) (thanks @dorukardahan)

---------

Co-authored-by: Tyler Yust <[email protected]>

* fix(tui): preserve credential-like tokens in render sanitization

* CLI: make read-only SecretRef status flows degrade safely (#37023)

* CLI: add read-only SecretRef inspection

* CLI: fix read-only SecretRef status regressions

* CLI: preserve read-only SecretRef status fallbacks

* Docs: document read-only channel inspection hook

* CLI: preserve audit coverage for read-only SecretRefs

* CLI: fix read-only status account selection

* CLI: fix targeted gateway fallback analysis

* CLI: fix Slack HTTP read-only inspection

* CLI: align audit credential status checks

* CLI: restore Telegram read-only fallback semantics

* chore(changelog): update for #37023

Signed-off-by: joshavant <[email protected]>

* fix(agents): disable usage streaming chunks on non-native openai-completions

* feat(nano-banana-pro): add --aspect-ratio flag to generate_image.py (#28159)

* feat(nano-banana-pro): add --aspect-ratio flag to generate_image.py

* Nano Banana: allow all supported aspect ratios

* Docs: expand nano banana aspect ratio options

---------

Co-authored-by: Vincent Koc <[email protected]>

* fix(gateway): support image_url in OpenAI chat completions (#34068)

* fix(gateway): parse image_url in openai chat completions

* test(gateway): cover openai chat completions image_url flows

* docs(changelog): note openai image_url chat completions fix (#17685)

* fix(gateway): harden openai image_url parsing and limits

* test(gateway): add openai image_url regression coverage

* docs(changelog): expand #17685 openai chat completions note

* Gateway: make OpenAI image_url URL fetch opt-in and configurable

* Diagnostics: redact image base64 payload data in trace logs

* Changelog: note OpenAI image_url hardening follow-ups

* Gateway: enforce OpenAI image_url total budget incrementally

* Gateway: scope OpenAI image_url extraction to the active turn

* Update CHANGELOG.md

* fix(agents): avoid xAI web_search tool-name collisions

* fix: clear Telegram DM draft after materialize (#36746) (thanks @joelnishanth)

* Fix Control UI duplicate iMessage replies for internal webchat turns (#36151)

* Auto-reply: avoid routing external replies from internal webchat turns

* Auto-reply tests: cover internal webchat non-routing with external origin metadata

* Changelog: add Control UI iMessage duplicate-reply fix note

* Auto-reply context: track explicit deliver routes

* Gateway chat: mark explicit external deliver routes in context

* Auto-reply: preserve explicit deliver routes for internal webchat turns

* Auto-reply tests: cover explicit deliver routes from internal webchat turns

* Gateway chat tests: assert explicit deliver route context tagging

* fix: enforce 600 perms for cron store and run logs (#36078)

* fix: enforce secure permissions for cron store and run logs

* fix(cron): enforce dir perms and gate posix tests on windows

* Cron store tests: cover existing directory permission hardening

* Cron run-log tests: cover existing directory permission hardening

* Changelog: note cron file permission hardening

---------

Co-authored-by: linhey <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>

* fix(tui): accept canonical session-key aliases in chat event routing

* Gateway: normalize OpenAI stream chunk text

* Gateway: coerce chat deliverable route boolean

* fix(web_search): align brave language codes with API

* Respect source channel for agent event surfacing (#36030)

* fix(session): prefer webchat routes for direct ui turns (#37135)

* Gateway: discriminate input sources

* Cron: migrate legacy provider delivery hints

* Cron: stabilize runs-one-shot migration tests

* fix(memory): retry mcporter after Windows EINVAL spawn

* fix(onboarding): guard daemon status probe on headless linux

* Gateway: add path-scoped config schema lookup (#37266)

Merged via squash.

Prepared head SHA: 0c4d187f6fb66f2799d4047585d6368e433c883a
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* docs(changelog): add pr entry

* fix(ci): restore protocol and schema checks (#37470)

* Fix failover for zhipuai 1310 Weekly/Monthly Limit Exhausted (#33813)

Merged via squash.

Prepared head SHA: 3dc441e58de48913720cf7b6137fa761758d8344
Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* fix(openai-codex-oauth): stop mutating authorize url scopes

* Update CHANGELOG.md

* fix(auth): remove bogus codex oauth responses probe

* docs(changelog): fold codex oauth fix notes

* docs(changelog): add codex oauth pr reference (#37558)

* fix(security:PLA-697): block local secret scratch files from commits

* feat: add dev EKS deployment for openclaw SRE container

* fix: stabilize slack socket mode in dev eks runtime

* fix(eks): reuse monitoring incident auth for openclaw-sre

* feat(deploy): add grafana env guards and prod deploy wrapper

* fix(security): redact tool outputs and enforce secret-safe runtime defaults

* feat(sre): harden heartbeat routing and enrich triage signals

* docs: add SRE hybrid intelligence design

Three-layer architecture to improve bot reasoning quality:
- Layer 1: Service knowledge (auto-discovery + overlays + incident memory)
- Layer 2: Multi-stage reasoning chain (triage → hypothesize → causal chain → action plan → cross-review)
- Layer 3: Incident learning loop (structured cards, overlay suggestions, feedback signals)

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* feat(sandbox): add boundary cli to common runtime image

* docs(sre): finalize hybrid intelligence design v19 after 18 Codex review rounds

Iteratively hardened the design through 18 adversarial Codex review rounds,
resolving 60+ findings (15+ CRITICAL, 45+ HIGH). Key fixes include:
- Decoupled incident_id (pre-Step11 immutable) from card_id (LLM-derived)
- Unified evidence/memory sanitization via shared _strip_instruction_tokens
- Fixed rerun interval default (3600s > heartbeat 1800s) to prevent every-cycle re-runs
- Added Phase 2 cross-review gap note and dual-column depth table
- Overlay suggestion idempotency via deterministic suggestion_key + upsert
- Decoupled chain timeout from legacy budget check
- Added predicate alignment docs for L3 pre-check vs L3 gate
- Adopted dynamic evidence_completeness denominator matching existing code
- Added scope note clarifying design vs current implementation

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* feat(sre): complete hybrid intelligence rollout and bot hardening

* fix(sre): harden slack reasoning, dual chain, and deploy auth/runtime

* ci: add ecr release pipeline and infra-helm image update trigger

* ci: switch workflows to github-hosted runners

* ci: allow manual ecr env target and use updater v4

* ci: remove windows jobs from workflow

* chore(pla-678): update fallback auth fixture and plan docs

* fix(pla-678): preserve control-ui host-header fallback in dev config

* refactor(pla-678): remove local sre chart and require infra-helm

* refactor(pla-678): remove direct eks deploy scripts

* ci(pla-678): remove labeler workflow

* ci(pla-678): refresh checks after disabling labeler

* build: install boundary CLI in SRE runtime image

* fix(slack:PLA-678): keep one thread lane across users

* fix(sre-skill): enforce live db-query runbook in dev seed

* fix(slack): ignore bot thread history when seeding new sessions

* fix(slack): force retry on repeated thread questions

* fix(sre-skill): require retry on repeated db requests

* docs(sre-skill): make retry policy generic across repeated asks

* fix(sre:PLA-678): enforce live linear ticket updates

* fix(sre:PLA-678): use [PLATFORM] Backlog linear project

* fix(sre:PLA-678): label linked linear tickets as openclaw-sre

* fix(sre:PLA-678): auto-label linked linear tickets for auto-pr

* test(sre:PLA-678): make tracking label test executable

* fix(slack:PLA-678): remove status-final completion banner (#16)

* fix(slack:PLA-678): enable direct file attachments from agent replies (#17)

* fix(slack:PLA-678): remove status-final completion banner

* fix(slack): enable direct file attachments from agent replies

* refactor(sre:PLA-678): remove local deploy config mirror (#18)

* fix: compact oversized auto-generated pr bodies

* fix(sre): add built-in linear incident memory provider

* feat(sre): add erpc helper with flo secret query

* fix(sre): enforce canonical rpc.morpho.dev erpc endpoint

* refactor(sre): remove local deploy config mirror

* fix(slack:PLA-678): force DM replies into per-message threads (#19)

* fix: compact oversized auto-generated pr bodies

* fix(sre): add built-in linear incident memory provider

* feat(sre): add erpc helper with flo secret query

* fix(sre): enforce canonical rpc.morpho.dev erpc endpoint

* refactor(sre): remove local deploy config mirror

* fix(slack): force threaded replies for direct messages

* feat(cron:PLA-678): use conversation history in self-improve runs (#20)

* fix(slack:PLA-678): improve progress update readability (#21)

* fix(ci:PLA-678): restore main release pipeline health (#22)

* fix(ci:PLA-678): restore main release pipeline health

* fix(ci:PLA-678): harden auto-response token fallback

* fix(ci:PLA-678): pin setup-bun to published release

* test(ci:PLA-678): align slack thread session expectations

* fix(sre:PLA-678): harden Slack reply delivery and image release flow (#23)

* fix(slack:PLA-678): harden thread-scoped reply delivery

* fix(slack:PLA-678): satisfy lint after rebase

* ci(release:PLA-678): move image release to cached ecr flow

* ci(release:PLA-678): use official docker build actions

* fix(slack:PLA-722): preserve progress updates during final-answer gating (#24)

* fix(sre:PLA-724): restore ECR runtime image toolchain (#25)

* fix(failover): classify HTTP 402 as rate_limit when payload indicates usage limit (#30484) (#36802)

* fix(failover): classify HTTP 402 as rate_limit when payload indicates usage limit (#30484)

Some providers (notably Anthropic Claude Max plan) surface temporary
usage/rate-limit failures as HTTP 402 instead of 429. Before this change,
all 402s were unconditionally mapped to 'billing', which produced a
misleading 'run out of credits' warning for Max plan users who simply
hit their usage window.

This follows the same pattern introduced for HTTP 400 in #36783: check
the error message for an explicit rate-limit signal before falling back
to the default status-code classification.

- classifyFailoverReasonFromHttpStatus now returns 'rate_limit' for 402
  when isRateLimitErrorMessage matches the payload text
- Added regression tests covering both the rate-limit and billing paths
  on 402

* fix: narrow 402 rate-limit matcher to prevent billing misclassification

The original implementation used isRateLimitErrorMessage(), which matches
phrases like 'quota exceeded' that legitimately appear in billing errors.

This commit replaces it with a narrow, 402-specific matcher that requires
BOTH retry language (try again/retry/temporary/cooldown) AND limit
terminology (usage limit/rate limit/organization usage).

Prevents misclassification of errors like:
'HTTP 402: exceeded quota, please add credits' -> billing (not rate_limit)

Added regression test for the ambiguous case.

---------

Co-authored-by: Val Alexander <[email protected]>

* fix(mattermost): allow reachable interaction callback URLs (#37543)

Merged via squash.

Prepared head SHA: 4d593731be5a5dcbf3106d596b38acfeb8cf0aa8
Co-authored-by: mukhtharcm <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

---------

Signed-off-by: joshavant <[email protected]>
Co-authored-by: Gustavo Madeira Santana <[email protected]>
Co-authored-by: Mariano <[email protected]>
Co-authored-by: leepokai <[email protected]>
Co-authored-by: Bob <[email protected]>
Co-authored-by: Onur <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: huangcj <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: Sid <[email protected]>
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Co-authored-by: a <[email protected]>
Co-authored-by: echoVic <[email protected]>
Co-authored-by: Shakker <[email protected]>
Co-authored-by: liuxiaopai-ai <[email protected]>
Co-authored-by: Rodrigo Uroz <[email protected]>
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: jalehman <[email protected]>
Co-authored-by: Kai <[email protected]>
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: 青雲 <[email protected]>
Co-authored-by: echoVic <[email protected]>
Co-authored-by: Darshil <[email protected]>
Co-authored-by: Ho Lim <[email protected]>
Co-authored-by: dvrshil <[email protected]>
Co-authored-by: Isis Anisoptera <[email protected]>
Co-authored-by: Madoka <[email protected]>
Co-authored-by: Xu Zimo <[email protected]>
Co-authored-by: Munem Hashmi <[email protected]>
Co-authored-by: bmendonca3 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: Nhj <[email protected]>
Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: rexl2018 <[email protected]>
Co-authored-by: sline <[email protected]>
Co-authored-by: 0xsline <[email protected]>
Co-authored-by: Harold Hunt <[email protected]>
Co-authored-by: Shivam <[email protected]>
Co-authored-by: 不做了睡大觉 <[email protected]>
Co-authored-by: alexyyyander <[email protected]>
Co-authored-by: alexyyyander <[email protected]>
Co-authored-by: Octane0411 <[email protected]>
Co-authored-by: Linux2010 <[email protected]>
Co-authored-by: echoVic <[email protected]>
Co-authored-by: Joseph Turian <[email protected]>
Co-authored-by: turian <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Tony Dehnke <[email protected]>
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: kevinWangSheng <[email protected]>
Co-authored-by: ningding97 <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: clawbie <[email protected]>
Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Ayane <[email protected]>
Co-authored-by: Ayane <[email protected]>
Co-authored-by: StingNing <[email protected]>
Co-authored-by: maweibin <[email protected]>
Co-authored-by: maweibin <[email protected]>
Co-authored-by: Josh Avant <[email protected]>
Co-authored-by: Bin Deng <[email protected]>
Co-authored-by: Byungsker <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Co-authored-by: Altay <[email protected]>
Co-authored-by: jiangnan <[email protected]>
Co-authored-by: jnMetaCode <[email protected]>
Co-authored-by: Jacob Riff <[email protected]>
Co-authored-by: jriff <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: Bill <[email protected]>
Co-authored-by: 2233admin <[email protected]>
Co-authored-by: 2233admin <[email protected]>
Co-authored-by: littleben <[email protected]>
Co-authored-by: littleben <[email protected]>
Co-authored-by: OpenClaw Agent <[email protected]>
Co-authored-by: Vignesh Natarajan <[email protected]>
Co-authored-by: zerone0x <[email protected]>
Co-authored-by: zerone0x <[email protected]>
Co-authored-by: dunamismax <[email protected]>
Co-authored-by: Octane <[email protected]>
Co-authored-by: Mitsuyuki Osabe <[email protected]>
Co-authored-by: Tak <[email protected]>
Co-authored-by: Tyler Yust <[email protected]>
Co-authored-by: Hinata Kaga (samon) <[email protected]>
Co-authored-by: dorukardahan <[email protected]>
Co-authored-by: Tyler Yust <[email protected]>
Co-authored-by: Brenner Spear <[email protected]>
Co-authored-by: aerelune <[email protected]>
Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: Vignesh <[email protected]>
Co-authored-by: OpenClaw SRE Bot <[email protected]>
Co-authored-by: Xinhua Gu <[email protected]>
Co-authored-by: Val Alexander <[email protected]>
0x666c6f added a commit to 0x666c6f/openclaw that referenced this pull request Mar 26, 2026
)

* Plugins/matrix: migrate to scoped plugin-sdk imports

* Plugins/mattermost: migrate to scoped plugin-sdk imports

* Plugins/memory-core: migrate to scoped plugin-sdk imports

* Plugins/memory-lancedb: migrate to scoped plugin-sdk imports

* Plugins/minimax-portal-auth: migrate to scoped plugin-sdk imports

* Plugins/msteams: migrate to scoped plugin-sdk imports

* Plugins/nextcloud-talk: migrate to scoped plugin-sdk imports

* Plugins/nostr: migrate to scoped plugin-sdk imports

* Plugins/open-prose: migrate to scoped plugin-sdk imports

* Plugins/phone-control: migrate to scoped plugin-sdk imports

* Plugins/qwen-portal-auth: migrate to scoped plugin-sdk imports

* Plugins/synology-chat: migrate to scoped plugin-sdk imports

* Plugins/talk-voice: migrate to scoped plugin-sdk imports

* Plugins/test-utils: migrate to scoped plugin-sdk imports

* Plugins/thread-ownership: migrate to scoped plugin-sdk imports

* Plugins/tlon: migrate to scoped plugin-sdk imports

* Plugins/twitch: migrate to scoped plugin-sdk imports

* Plugins/voice-call: migrate to scoped plugin-sdk imports

* Plugins/whatsapp: migrate to scoped plugin-sdk imports

* Plugins/zalo: migrate to scoped plugin-sdk imports

* Plugins/zalouser: migrate to scoped plugin-sdk imports

* Chore: remove accidental .DS_Store artifact

* chore(docs): add plugins refactor changelog entry

* feat(ios): add Live Activity connection status + stale cleanup (#33591)

* feat(ios): add live activity connection status and cleanup

Add lock-screen/Dynamic Island connection health states and prune duplicate/stale activities before reuse. This intentionally excludes AI/title generation and heavier UX rewrites from #27488.

Co-authored-by: leepokai <[email protected]>

* fix(ios): treat ended live activities as inactive

* chore(changelog): add PR reference and author thanks

---------

Co-authored-by: leepokai <[email protected]>

* fix: kill stuck ACP child processes on startup and harden sessions in discord threads (#33699)

* Gateway: resolve agent.wait for chat.send runs

* Discord: harden ACP thread binding + listener timeout

* ACPX: handle already-exited child wait

* Gateway/Discord: address PR review findings

* Discord: keep ACP error-state thread bindings on startup

* gateway: make agent.wait dedupe bridge event-driven

* discord: harden ACP probe classification and cap startup fan-out

* discord: add cooperative timeout cancellation

* discord: fix startup probe concurrency helper typing

* plugin-sdk: avoid Windows root-alias shard timeout

* plugin-sdk: keep root alias reflection path non-blocking

* discord+gateway: resolve remaining PR review findings

* gateway+discord: fix codex review regressions

* Discord/Gateway: address Codex review findings

* Gateway: keep agent.wait lifecycle active with shared run IDs

* Discord: clean up status reactions on aborted runs

* fix: add changelog note for ACP/Discord startup hardening (#33699) (thanks @dutifulbob)

---------

Co-authored-by: Onur <[email protected]>

* fix: relay ACP sessions_spawn parent streaming (#34310) (thanks @vincentkoc) (#34310)

Co-authored-by: Onur Solmaz <[email protected]>

* fix(telegram): materialize dm draft final to avoid duplicates

* docs(changelog): credit @Brotherinlaw-13 for #34318

* fix: prevent nodes media base64 context bloat (#34332)

* fix: preserve raw media invoke for HTTP tool clients (#34365)

* fix(slack): route system events to bound agent sessions (#34045)

* fix(slack): route system events via binding-aware session keys

* fix(slack): pass sender to system event session resolver

* fix(slack): include sender context for interaction session routing

* fix(slack): include modal submitter in session routing

* test(slack): cover binding-aware system event routing

* test(slack): update interaction session key assertions

* test(slack): assert reaction session routing carries sender

* docs(changelog): note slack system event routing fix

* Update CHANGELOG.md

* Delete changelog/fragments directory

* fix(memory): serialize local embedding initialization to avoid duplicate model loads (#15639)

Merged via squash.

Prepared head SHA: a085fc21a8ba7163fffdb5de640dd4dc1ff5a88e
Co-authored-by: SubtleSpark <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(model): propagate custom provider headers to model objects (#27490)

Merged via squash.

Prepared head SHA: e4183b398fc7eb4c18b2b691cb0dd882ec993608
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(daemon): handle systemctl is-enabled exit 4 (not-found) on Ubuntu (#33634)

Merged via squash.

Prepared head SHA: 67dffc3ee239cd7b813cb200c3dd5475d9e203a6
Co-authored-by: Yuandiaodiaodiao <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(node-host): sync rawCommand with hardened argv after executable path pinning (#33137)

Merged via squash.

Prepared head SHA: a7987905f7ad6cf5fee286ffa81ceaad8297174f
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* Agents: add generic poll-vote action support

* fix(ollama): pass provider headers to Ollama stream function (#24285)

createOllamaStreamFn() only accepted baseUrl, ignoring custom headers
configured in models.providers.<provider>.headers. This caused 403
errors when Ollama endpoints are behind reverse proxies that require
auth headers (e.g. X-OLLAMA-KEY via HAProxy).

Add optional defaultHeaders parameter to createOllamaStreamFn() and
merge them into every fetch request. Provider headers from config are
now passed through at the call site in the embedded runner.

Fixes #24285

* test(ollama): add default header precedence coverage

* chore(changelog): add PR entry openclaw#24337 thanks @echoVic

* Outbound: allow text-only plugin adapters

* Outbound: avoid empty multi-media fallback sends

* chore(changelog): align outbound adapter entry openclaw#32788 thanks @liuxiaopai-ai

* fix(outbound): fail media-only text-only adapter fallback

* chore(changelog): clarify outbound media-only fallback openclaw#32788 thanks @liuxiaopai-ai

* fix(review): enforce behavioral sweep validation

* Fix gateway restart false timeouts on Debian/systemd (#34874)

* daemon(systemd): target sudo caller user scope

* test(systemd): cover sudo user scope commands

* infra(ports): fall back to ss when lsof missing

* test(ports): verify ss fallback listener detection

* cli(gateway): use probe fallback for restart health

* test(gateway): cover restart-health probe fallback

* Compaction/Safeguard: require structured summary headings (#25555)

Merged via squash.

Prepared head SHA: 0b1df34806a7b788261290be55760fd89220de53
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Fix Linux daemon install checks when systemd user bus env is missing (#34884)

* daemon(systemd): fall back to machine user scope when user bus is missing

* test(systemd): cover machine scope fallback for user-bus errors

* test(systemd): reset execFile mock state across cases

* test(systemd): make machine-user fallback assertion portable

* fix(daemon): keep root sudo path on direct user scope

* test(systemd): cover sudo root user-scope behavior

* ci: use resolvable bun version in setup-node-env

* agents: preserve totalTokens on request failure instead of using contextWindow (#34275)

Merged via squash.

Prepared head SHA: f9d111d0a79a07815d476356e98a28df3a0000ba
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix: align AGENTS.md template section names with post-compaction extraction (#25029) (#25098)

Merged via squash.

Prepared head SHA: 8cd6cc8049aab5a94d8a9d5fb08f2e792c4ac5fd
Co-authored-by: echoVic <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Changelog: add daemon systemd user-bus fallback entry (#34884)

* Changelog: add gateway restart health entry (#34874)

* fix: finalize spanish locale support

* fix: add spanish locale support (#35038) (thanks @DaoPromociones)

* fix(deps): patch hono transitive audit vulnerabilities

* fix(security): avoid prototype-chain account path checks (#34982)

Merged via squash.

Prepared head SHA: f89cc6a649959997fe1dec1e1c1bff9a61b2de98
Co-authored-by: HOYALIM <[email protected]>
Co-authored-by: dvrshil <[email protected]>
Reviewed-by: @dvrshil

* fix(deps): bump tar to 7.5.10

* docs(changelog): document dependency security fixes

* fix: restore auto-reply system events timeline (#34794) (thanks @anisoptera) (#34794)

Co-authored-by: Ayaan Zaidi <[email protected]>

* fix(feishu): comprehensive reply mechanism — outbound replyToId forwarding + topic-aware reply targeting (#33789)

* fix(feishu): comprehensive reply mechanism fix — outbound replyToId forwarding + topic-aware reply targeting

- Forward replyToId from ChannelOutboundContext through sendText/sendMedia
  to sendMessageFeishu/sendMarkdownCardFeishu/sendMediaFeishu, enabling
  reply-to-message via the message tool.

- Fix group reply targeting: use ctx.messageId (triggering message) in
  normal groups to prevent silent topic thread creation (#32980). Preserve
  ctx.rootId targeting for topic-mode groups (group_topic/group_topic_sender)
  and groups with explicit replyInThread config.

- Add regression tests for both fixes.

Fixes #32980
Fixes #32958
Related #19784

* fix: normalize Feishu delivery.to before comparing with messaging tool targets

- Add normalizeDeliveryTarget helper to strip user:/chat: prefixes for Feishu
- Apply normalization in matchesMessagingToolDeliveryTarget before comparison
- This ensures cron duplicate suppression works when session uses prefixed targets
  (user:ou_xxx) but messaging tool extract uses normalized bare IDs (ou_xxx)

Fixes review comment on PR #32755

(cherry picked from commit fc20106f16ccc88a5f02e58922bb7b7999fe9dcd)

* fix(feishu): catch thrown SDK errors for withdrawn reply targets

The Feishu Lark SDK can throw exceptions (SDK errors with .code or
AxiosErrors with .response.data.code) for withdrawn/deleted reply
targets, in addition to returning error codes in the response object.

Wrap reply calls in sendMessageFeishu and sendCardFeishu with
try-catch to handle thrown withdrawn/not-found errors (230011,
231003) and fall back to client.im.message.create, matching the
existing response-level fallback behavior.

Also extract sendFallbackDirect helper to deduplicate the
direct-send fallback block across both functions.

Closes #33496

(cherry picked from commit ad0901aec103a2c52f186686cfaf5f8ba54b4a48)

* feishu: forward outbound reply target context

(cherry picked from commit c129a691fcf552a1cebe1e8a22ea8611ffc3b377)

* feishu extension: tighten reply target fallback semantics

(cherry picked from commit f85ec610f267020b66713c09e648ec004b2e26f1)

* fix(feishu): align synthesized fallback typing and changelog attribution

* test(feishu): cover group_topic_sender reply targeting

---------

Co-authored-by: Xu Zimo <[email protected]>
Co-authored-by: Munem Hashmi <[email protected]>
Co-authored-by: bmendonca3 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(feishu): use msg_type media for mp4 video (fixes #33674) (#33720)

* fix(feishu): use msg_type media for mp4 video (fixes #33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw/openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(agents): bypass pendingDescendantRuns guard for cron announce delivery (#35185)

* fix(agents): bypass pendingDescendantRuns guard for cron announce delivery

Standalone cron job completions were blocked from direct channel delivery
when the cron run had spawned subagents that were still registered as
pending. The pendingDescendantRuns guard exists for live orchestration
coordination and should not apply to fire-and-forget cron announce sends.

Thread the announceType through the delivery chain and skip both the
child-descendant and requester-descendant pending-run guards when the
announce originates from a cron job.

Closes #34966

* fix: ensure outbound session entry for cron announce with named agents (#32432)

Named agents may not have a session entry for their delivery target,
causing the announce flow to silently fail (delivered=false, no error).

Two fixes:
1. Call ensureOutboundSessionEntry when resolving the cron announce
   session key so downstream delivery can find channel metadata.
2. Fall back to direct outbound delivery when announce delivery fails
   to ensure cron output reaches the target channel.

Closes #32432

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: guard announce direct-delivery fallback against suppression leaks (#32432)

The `!delivered` fallback condition was too broad — it caught intentional
suppressions (active subagents, interim messages, SILENT_REPLY_TOKEN) in
addition to actual announce delivery failures.  Add an
`announceDeliveryWasAttempted` flag so the direct-delivery fallback only
fires when `runSubagentAnnounceFlow` was actually called and failed.

Also remove the redundant `if (route)` guard in
`resolveCronAnnounceSessionKey` since `resolved` being truthy guarantees
`route` is non-null.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix(cron): harden announce synthesis follow-ups

---------

Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* Feishu: harden streaming merge semantics and final reply dedupe (#33245)

* Feishu: close duplicate final gap and cover routing precedence

* Feishu: resolve reviewer duplicate-final and routing feedback

* Feishu: tighten streaming send-mode option typing

* Feishu: fix reverse-overlap streaming merge ordering

* Feishu: align streaming final dedupe test expectation

* Feishu: allow distinct streaming finals while deduping repeats

---------

Co-authored-by: Tak Hoffman <[email protected]>

* fix: cron backup should preserve pre-edit snapshot (#35195) (#35234)

* fix(cron): avoid overwriting .bak during normalization

Fixes openclaw/openclaw#35195

* test(cron): preserve pre-edit bak snapshot in normalization path

---------

Co-authored-by: 0xsline <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(cron): stabilize restart catch-up replay semantics (#35351)

* Cron: stabilize restart catch-up replay semantics

* Cron: respect backoff in startup missed-run replay

* cron: narrow startup replay backoff guard (#35391)

* cron: unify stale-run recovery and preserve manual-run every anchors (#35363)

* cron: unify stale-run recovery and preserve manual every anchors

* cron: address unresolved review threads on recovery paths

* cron: remove duplicate timestamp helper after rebase

* refactor(telegram): remove unused webhook callback helper (#27816)

* fix(pr): make review claim step required

* fix(skills): deduplicate slash commands by skillName across all interfaces

Move skill-command deduplication by skillName from the Discord-only
`dedupeSkillCommandsForDiscord` into `listSkillCommandsForAgents` so
every interface (TUI, Slack, text) consistently sees a clean command
list without platform-specific workarounds.

When multiple agents share a skill with the same name the old code
emitted `github` + `github_2` and relied on Discord to collapse them.
Now `listSkillCommandsForAgents` returns only the first registration
per skillName, and the Discord-specific wrapper is removed.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* style: fix formatting in skill-commands.test.ts and provider.ts

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* style(skills): align formatting cleanup for dedupe changes

* chore(changelog): add dedupe note openclaw#27521 thanks @shivama205

* fix(agents): detect Venice provider proxying xAI/Grok models for schema cleaning (#35355)

Merged via squash.

Prepared head SHA: 8bfdec257bb6a6025cb69a0a213a433da32b15db
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(agents): decode HTML entities in xAI/Grok tool call arguments (#35276)

Merged via squash.

Prepared head SHA: c4445d2938898ded9c046614f9315dbda65ec573
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(agents): guard promoteThinkingTagsToBlocks against malformed content entries (#35143)

Merged via squash.

Prepared head SHA: 3971122f5fd27c66c8c9c5ce783f00e113b1f47b
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(web-ui): render Accounts schema node properly (#35380)

Co-authored-by: stakeswky <[email protected]>
Co-authored-by: liuxiaopai-ai <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(agents): guard context pruning against malformed thinking blocks (#35146)

Merged via squash.

Prepared head SHA: a196a565b1b8e806ffbf85172bcf1128796b45a2
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(gateway): prevent internal route leakage in chat.send

Synthesis of routing fixes from #35321, #34635, and #35356 for internal-client reply safety.

- Require explicit `deliver: true` before inheriting any external delivery route.
- Keep webchat/TUI/UI-origin traffic on internal routing by default.
- Allow configured-main session inheritance only for non-Webchat/UI clients, and honor `session.mainKey`.
- Add regression tests for UI no-inherit, configured-main CLI inherit, and deliver-flag behavior.

Co-authored-by: alexyyyander <[email protected]>
Co-authored-by: Octane0411 <[email protected]>
Co-authored-by: Linux2010 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(gateway): pass actual version to Control UI client instead of dev (#35230)

* fix(gateway): pass actual version to Control UI client instead of "dev"

The GatewayClient, CLI WS client, and browser Control UI all sent
"dev" as their clientVersion during handshake, making it impossible
to distinguish builds in gateway logs and health snapshots.

- GatewayClient and CLI WS client now use the resolved VERSION constant
- Control UI reads serverVersion from the bootstrap endpoint and
  forwards it when connecting
- Bootstrap contract extended with serverVersion field

Closes #35209

* Gateway: fix control-ui version version-reporting consistency

* Control UI: guard deferred bootstrap connect after disconnect

* fix(ui): accept same-origin http and relative gateway URLs for client version

---------

Co-authored-by: Tak Hoffman <[email protected]>

* chore(pr): enforce changelog placement and reduce merge sync churn

* TTS: add baseUrl support to OpenAI TTS config (#34321)

Merged via squash.

Prepared head SHA: e9a10cf81d2021cf81091dfa81e13ffdbb6a540a
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* ACP: add persistent Discord channel and Telegram topic bindings (#34873)

* docs: add ACP persistent binding experiment plan

* docs: align ACP persistent binding spec to channel-local config

* docs: scope Telegram ACP bindings to forum topics only

* docs: lock bound /new and /reset behavior to in-place ACP reset

* ACP: add persistent discord/telegram conversation bindings

* ACP: fix persistent binding reuse and discord thread parent context

* docs: document channel-specific persistent ACP bindings

* ACP: split persistent bindings and share conversation id helpers

* ACP: defer configured binding init until preflight passes

* ACP: fix discord thread parent fallback and explicit disable inheritance

* ACP: keep bound /new and /reset in-place

* ACP: honor configured bindings in native command flows

* ACP: avoid configured fallback after runtime bind failure

* docs: refine ACP bindings experiment config examples

* acp: cut over to typed top-level persistent bindings

* ACP bindings: harden reset recovery and native command auth

* Docs: add ACP bound command auth proposal

* Tests: normalize i18n registry zh-CN assertion encoding

* ACP bindings: address review findings for reset and fallback routing

* ACP reset: gate hooks on success and preserve /new arguments

* ACP bindings: fix auth and binding-priority review findings

* Telegram ACP: gate ensure on auth and accepted messages

* ACP bindings: fix session-key precedence and unavailable handling

* ACP reset/native commands: honor fallback targets and abort on bootstrap failure

* Config schema: validate ACP binding channel and Telegram topic IDs

* Discord ACP: apply configured DM bindings to native commands

* ACP reset tails: dispatch through ACP after command handling

* ACP tails/native reset auth: fix target dispatch and restore full auth

* ACP reset detection: fallback to active ACP keys for DM contexts

* Tests: type runTurn mock input in ACP dispatch test

* ACP: dedup binding route bootstrap and reset target resolution

* reply: align ACP reset hooks with bound session key

* docs: replace personal discord ids with placeholders

* fix: add changelog entry for ACP persistent bindings (#34873) (thanks @dutifulbob)

---------

Co-authored-by: Onur <[email protected]>

* docs(telegram): recommend allowlist for single-user DM policy (#34841)

* docs(telegram): recommend allowlist for single-user bots

* docs(telegram): condense single-user allowlist note

---------

Co-authored-by: echoVic <[email protected]>

* fix(feishu): check response.ok before calling response.json() in streaming card (#35628)

Merged via squash.

Prepared head SHA: 62c3fec80d97cea9be344c0bef5358a0a5dc5560
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Mattermost: honor onmessage mention override and add gating diagnostics tests (#27160)

Merged via squash.

Prepared head SHA: 6cefb1d5bf3d6dfcec36c1cee3f9ea887f10c890
Co-authored-by: turian <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* fix(subagents): strip leaked [[reply_to]] tags from completion announces (#34503)

* fix(subagents): strip reply tags from completion delivery text

* test(subagents): cover reply-tag stripping in cron completion sends

* changelog: note iMessage reply-tag stripping in completion announces

* Update CHANGELOG.md

* Apply suggestion from @greptile-apps[bot]

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix(cron): restore direct fallback after announce failure in best-effort mode (openclaw#36177)

Verified:
- pnpm build
- pnpm check (fails on pre-existing origin/main lint debt in extensions/mattermost imports)
- pnpm test:macmini

Co-authored-by: Tak Hoffman <[email protected]>

* test(cron): add cross-channel announce fallback regression coverage (openclaw#36197)

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check (fails on pre-existing origin/main lint debt in extensions/mattermost imports)
- pnpm test:macmini

Co-authored-by: Tak Hoffman <[email protected]>

* feat(mattermost): add interactive buttons support (#19957)

Merged via squash.

Prepared head SHA: 8a25e608729d0b9fd07bb0ee4219d199d9796dbe
Co-authored-by: tonydehnke <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* fix(browser): remove deprecated --disable-blink-features=AutomationControlled flag

- Removes OpenClaw's default `--disable-blink-features=AutomationControlled` Chrome launch switch to avoid unsupported-flag warnings in newer Chrome (#35721).
- Preserves compatibility for older Chrome via `browser.extraArgs` override behavior (source analysis: #35770, #35728, #35727, #35885).
- Synthesis attribution: thanks @Sid-Qin, @kevinWangSheng, @ningding97, @Naylenv, @clawbie.

Source PR refs: #35734, #35770, #35728, #35727, #35885

Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: kevinWangSheng <[email protected]>
Co-authored-by: ningding97 <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: clawbie <[email protected]>
Co-authored-by: Takhoffman <[email protected]>

* fix(feishu): add HTTP timeout to prevent per-chat queue deadlocks (#36430)

When the Feishu API hangs or responds slowly, the sendChain never settles,
causing the per-chat queue to remain in a processing state forever and
blocking all subsequent messages in that thread. This adds a 30-second
default timeout to all Feishu HTTP requests by providing a timeout-aware
httpInstance to the Lark SDK client.

Closes #36412

Co-authored-by: Ayane <[email protected]>

* fix(feishu): use probed botName for mention checks (#36391)

* Feishu: honor bot mentions by ID despite aliases (Fixes #36317) (#36333)

* Mattermost: switch plugin-sdk imports to scoped subpaths (openclaw#36480)

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(feishu): accept groupPolicy "allowall" as alias for "open" (#36358)

* fix(feishu): accept groupPolicy "allowall" as alias for "open"

When users configure groupPolicy: "allowall" in Feishu channel config,
the Zod schema rejects the value and the runtime policy check falls
through to the allowlist path.  With an empty allowFrom array, all group
messages are silently dropped despite the intended "allow all" semantics.

Accept "allowall" at the schema level (transform to "open") and add a
runtime guard in isFeishuGroupAllowed so the value is handled even if it
bypasses schema validation.

Closes #36312

Made-with: Cursor

* Feishu: tighten allowall alias handling and coverage

---------

Co-authored-by: Tak Hoffman <[email protected]>

* synthesis: fix Feishu group mention slash parsing

## Summary\n\nFeishu group slash command parsing is fixed for mentions and command probes across authorization paths.\n\nThis includes:\n- Normalizing bot mention text in group context for reliable slash detection in message parsing.\n- Adding command-probe normalization for group slash invocations.\n\nCo-authored-by: Sid Qin <[email protected]>\nCo-authored-by: Tak Hoffman <[email protected]>

* Feishu: normalize group slash command probing

- Feishu/group slash command detection: normalize group mention wrappers before command-authorization probing so mention-prefixed commands are recognized in group routing.\n- Source PR: #36011\n- Contributor: @liuxiaopai-ai\n\nCo-authored-by: Tak Hoffman <[email protected]>\nCo-authored-by: liuxiaopai-ai <[email protected]>

* add prependSystemContext and appendSystemContext to before_prompt_build (fixes #35131) (#35177)

Merged via squash.

Prepared head SHA: d9a2869ad69db9449336a2e2846bd9de0e647ac6
Co-authored-by: maweibin <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(feishu): avoid media regressions from global HTTP timeout (#36500)

* fix(feishu): avoid media regressions from global http timeout

* fix(feishu): source HTTP timeout from config

* fix(feishu): apply media timeout override to image uploads

* fix(feishu): invalidate cached client when timeout changes

* fix(feishu): clamp timeout values and cover image download

* Gateway: add SecretRef support for gateway.auth.token with auth-mode guardrails (#35094)

* fix(embedded): classify model_context_window_exceeded as context overflow, trigger compaction (#35934)

Merged via squash.

Prepared head SHA: 20fa77289c80b2807a6779a3df70440242bc18ca
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(agents): skip compaction API call when session has no real messages (#36451)

Merged via squash.

Prepared head SHA: 52dd6317895c7bd10855d2bd7dbbfc2f5279b68e
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(ui): catch marked.js parse errors to prevent Control UI crash (#36445)

- Prevent Control UI session render crashes when `marked.parse()` encounters pathological recursive markdown by safely falling back to escaped `<pre>` output.
- Tighten markdown fallback regression coverage and keep changelog attribution in sync for this crash-hardening path.

Co-authored-by: Bin Deng <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(session): archive old transcript on daily/scheduled reset to prevent orphaned files (#35493)

Merged via squash.

Prepared head SHA: 0d95549d752adecfc0b08d5cd55a8b8c75e264fe
Co-authored-by: byungsker <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(agents): set preserveSignatures to isAnthropic in resolveTranscriptPolicy (#32813)

Merged via squash.

Prepared head SHA: f522d21ca59a42abac554435a0aa646f6a34698d
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix: avoid false global rate-limit classification from generic cooldown text (#32972)

Merged via squash.

Prepared head SHA: 813c16f5afce415da130a917d9ce9f968912b477
Co-authored-by: stakeswky <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* refactor(agents): share failover HTTP status classification (#36615)

* fix(agents): classify transient failover statuses consistently

* fix(agents): preserve legacy failover status mapping

* fix(failover): narrow service-unavailable to require overload indicator (#32828) (#36646)

Merged via squash.

Prepared head SHA: 46fb4306127972d7635f371fd9029fbb9baff236
Co-authored-by: jnMetaCode <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* Compaction/Safeguard: add summary quality audit retries (#25556)

Merged via squash.

Prepared head SHA: be473efd1635616ebbae6e649d542ed50b4a827f
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* test(agents): add provider-backed failover regressions (#36735)

* test(agents): add provider-backed failover fixtures

* test(agents): cover more provider error docs

* test(agents): tighten provider doc fixtures

* Docs: add Slack typing reaction fallback

* Docs: update gateway config reference for Slack and TTS

* Docs: clarify OpenAI-compatible TTS endpoints

* Docs: document Control UI locale support

* Docs: cover heartbeat, cron, and plugin route updates

* fix(ui): bump dompurify to 3.3.2 (#36781)

* UI: bump dompurify to 3.3.2

* Deps: refresh dompurify lockfile

* UI: hoist lifecycle connect test mocks (#36788)

* fix(agents): classify insufficient_quota 400s as billing (#36783)

* feat: append UTC time alongside local time in shared Current time lines (#32423)

Merged via squash.

Prepared head SHA: 9e8ec13933b5317e7cff3f0bc048de515826c31a
Co-authored-by: jriff <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* fix(auth): grant senderIsOwner for internal channels with operator.admin scope (openclaw#35704)

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Naylenv <[email protected]>
Co-authored-by: Octane0411 <[email protected]>
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(config): prevent RangeError in merged schema cache key generation

Fix merged schema cache key generation for high-cardinality plugin/channel metadata by hashing incrementally instead of serializing one large aggregate string.

Includes changelog entry for the user-visible regression fix.

Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: Bill <[email protected]>

* fix(slack): propagate mediaLocalRoots through Slack send path

Restore Slack local file upload parity with CVE-era local media allowlist enforcement by threading `mediaLocalRoots` through the Slack send call chain.

- pass `ctx.mediaLocalRoots` from Slack channel action adapter into `handleSlackAction`
- add and forward `mediaLocalRoots` in Slack action context/send path
- pass `mediaLocalRoots` into `sendMessageSlack` for upload allowlist enforcement
- add changelog entry with attribution for this behavior fix

Co-authored-by: 2233admin <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(slack): preserve dedupe while recovering dropped app_mention (#34937)

This PR fixes Slack mention loss without reintroducing duplicate dispatches.

- Preserve seen-message dedupe at ingress to prevent duplicate processing.
- Allow a one-time app_mention retry only when the paired message event was previously dropped before dispatch.
- Add targeted race tests for both recovery and duplicate-prevention paths.

Co-authored-by: littleben <[email protected]>
Co-authored-by: OpenClaw Agent <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* README: add algal to contributors list (#2046)

* fix: decouple Discord inbound worker timeout from listener timeout (#36602) (thanks @dutifulbob) (#36602)

Co-authored-by: Onur Solmaz <[email protected]>

* plugins: enforce prompt hook policy with runtime validation (#36567)

Merged via squash.

Prepared head SHA: 6b9d883b6ae33628235fb02ce39c0d0f46a065bb
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(memory): avoid destructive qmd collection rebinds

* Harden Telegram poll gating and schema consistency (#36547)

Merged via squash.

Prepared head SHA: f77824419e3d166f727474a9953a063a2b4547f2
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(browser): close tracked tabs on session cleanup (#36666)

* Diffs: restore system prompt guidance (#36904)

Merged via squash.

Prepared head SHA: 1b3be3c87957c068473d5c86b9efba4a1a8503f2
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(routing): avoid full binding rescans in resolveAgentRoute (#36915)

* fix(gateway): honor insecure ws override for remote hostnames

* fix(llm-task): load runEmbeddedPiAgent from dist/extensionAPI in installs

* fix(auth): harden openai-codex oauth login path

* feat(telegram/acp): Topic Binding, Pin Binding Message, Fix Spawn Param Parsing (#36683)

* fix(acp): normalize unicode flags and Telegram topic binding

* feat(telegram/acp): restore topic-bound ACP and session bindings

* fix(acpx): clarify permission-denied guidance

* feat(telegram/acp): pin spawn bind notice in topics

* docs(telegram): document ACP topic thread binding behavior

* refactor(reply): share Telegram conversation-id resolver

* fix(telegram/acp): preserve bound session routing semantics

* fix(telegram): respect binding persistence and expiry reporting

* refactor(telegram): simplify binding lifecycle persistence

* fix(telegram): bind acp spawns in direct messages

* fix: document telegram ACP topic binding changelog (#36683) (thanks @huntharo)

---------

Co-authored-by: Onur <[email protected]>

* fix(gateway): preserve streamed prefixes across tool boundaries

* fix(tui): prevent stale model indicator after /model

* Memory: handle SecretRef keys in doctor embeddings (#36835)

Merged via squash.

Prepared head SHA: c1a3d0caae60115d886e8bfc9983c9533c773f04
Co-authored-by: joshavant <[email protected]>
Co-authored-by: joshavant <[email protected]>
Reviewed-by: @joshavant

* fix(openai-codex): request required oauth api scopes (#24720)

* fix(memory-flush): ban timestamped variant files in default flush prompt (#34951)

Merged via squash.

Prepared head SHA: efadda4988b460e6da07be72994d4951d64239d0
Co-authored-by: zerone0x <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(tui): render final event error when assistant output is empty (#14687)

* feat(agents): flush reply pipeline before compaction wait (#35489)

Merged via squash.

Prepared head SHA: 7dbbcc510b74b0e8d35eb750d24575e34b5d769a
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(secrets): harden api key normalization for ByteString headers

* fix(slack): remove double mrkdwn conversion in native streaming path

Remove redundant text normalization from Slack native streaming markdown_text flow so Markdown formatting is preserved.

Synthesis context: overlaps reviewed from #34931, #34759, #34716, #34682, #34814.

Co-authored-by: littleben <[email protected]>
Co-authored-by: dunamismax <[email protected]>
Co-authored-by: Octane <[email protected]>
Co-authored-by: Mitsuyuki Osabe <[email protected]>
Co-authored-by: Kai <[email protected]>
Co-authored-by: OpenClaw Agent <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(kimi-coding): normalize anthropic tool payload format

* fix(slack): thread channel ID through inbound context for reactions (#34831)

Slack reaction/thread context routing fixes via canonical synthesis of #34831.

Co-authored-by: Tak <[email protected]>

* fix(heartbeat): pin HEARTBEAT.md reads to workspace path

* fix(subagents): recover announce cleanup after kill/complete race

* feat(hooks): emit compaction lifecycle hooks (#16788)

* fix(auth): harden openai-codex oauth refresh fallback

* fix(subagents): announce delivery with descendant gating, frozen result refresh, and cron retry (#35080)

Thanks @tyler6204

* fix(agents): avoid synthetic tool-result writes on idle-timeout cleanup

* fix(agent): harden undici stream timeouts for long openai-completions runs

* fix(slack): record app_mention retry key before dedupe check (#37033)

- Prime app_mention retry allowance before dedupe so near-simultaneous message/app_mention races do not drop valid mentions.
- Prevent duplicate dispatch when app_mention wins the race and message prepare later succeeds.
- Prune dispatched mention keys and add regression coverage for both dropped and successful in-flight message outcomes.

Co-authored-by: Tak Hoffman <[email protected]>

* fix(agents): honor explicit rate-limit cooldown probes in fallback runs

* fix(agents): allow configured ollama endpoints without dummy api keys

* fix(memory): recover qmd updates from duplicate document constraints

* Doctor: warn on implicit heartbeat directPolicy (#36789)

* Changelog: note heartbeat directPolicy doctor warning

* Tests: cover heartbeat directPolicy doctor warning

* Doctor: warn on implicit heartbeat directPolicy

* Tests: cover per-agent heartbeat directPolicy warning

* Update CHANGELOG.md

* Plugins: clarify registerHttpHandler migration errors (#36794)

* Changelog: note plugin HTTP route migration diagnostics

* Tests: cover registerHttpHandler migration diagnostics

* Plugins: clarify registerHttpHandler migration errors

* Tests: cover registerHttpHandler diagnostic edge cases

* Plugins: tighten registerHttpHandler migration hint

* fix(memory): repair qmd collection name conflicts during ensure

* fix(memory): handle qmd search results without docid

* Plugins: avoid false integrity drift prompts on unpinned updates (#37179)

* Plugins: skip drift prompts for unpinned updates

* Plugins: cover unpinned integrity update behavior

* Changelog: add #37179 release note

* Delete changelog/fragments directory

* Update CHANGELOG.md

* fix(whatsapp): remove implicit [openclaw] self-chat prefix

* fix: remove config.schema from agent gateway tool (#7382)

Merged via squash.

Prepared head SHA: f34a7780690a941936b31899e2d096b8a07f4afc
Co-authored-by: kakuteki <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* feat(openai): add gpt-5.4 support for API and Codex OAuth (#36590)

* feat(openai): add gpt-5.4 support and priority processing

* feat(openai-codex): add gpt-5.4 oauth support

* fix(openai): preserve provider overrides in gpt-5.4 fallback

* fix(openai-codex): keep xhigh for gpt-5.4 default

* fix(models): preserve configured overrides in list output

* fix(models): close gpt-5.4 integration gaps

* fix(openai): scope service tier to public api

* fix(openai): complete prep followups for gpt-5.4 support (#36590) (thanks @dorukardahan)

---------

Co-authored-by: Tyler Yust <[email protected]>

* fix(tui): preserve credential-like tokens in render sanitization

* CLI: make read-only SecretRef status flows degrade safely (#37023)

* CLI: add read-only SecretRef inspection

* CLI: fix read-only SecretRef status regressions

* CLI: preserve read-only SecretRef status fallbacks

* Docs: document read-only channel inspection hook

* CLI: preserve audit coverage for read-only SecretRefs

* CLI: fix read-only status account selection

* CLI: fix targeted gateway fallback analysis

* CLI: fix Slack HTTP read-only inspection

* CLI: align audit credential status checks

* CLI: restore Telegram read-only fallback semantics

* chore(changelog): update for #37023

Signed-off-by: joshavant <[email protected]>

* fix(agents): disable usage streaming chunks on non-native openai-completions

* feat(nano-banana-pro): add --aspect-ratio flag to generate_image.py (#28159)

* feat(nano-banana-pro): add --aspect-ratio flag to generate_image.py

* Nano Banana: allow all supported aspect ratios

* Docs: expand nano banana aspect ratio options

---------

Co-authored-by: Vincent Koc <[email protected]>

* fix(gateway): support image_url in OpenAI chat completions (#34068)

* fix(gateway): parse image_url in openai chat completions

* test(gateway): cover openai chat completions image_url flows

* docs(changelog): note openai image_url chat completions fix (#17685)

* fix(gateway): harden openai image_url parsing and limits

* test(gateway): add openai image_url regression coverage

* docs(changelog): expand #17685 openai chat completions note

* Gateway: make OpenAI image_url URL fetch opt-in and configurable

* Diagnostics: redact image base64 payload data in trace logs

* Changelog: note OpenAI image_url hardening follow-ups

* Gateway: enforce OpenAI image_url total budget incrementally

* Gateway: scope OpenAI image_url extraction to the active turn

* Update CHANGELOG.md

* fix(agents): avoid xAI web_search tool-name collisions

* fix: clear Telegram DM draft after materialize (#36746) (thanks @joelnishanth)

* Fix Control UI duplicate iMessage replies for internal webchat turns (#36151)

* Auto-reply: avoid routing external replies from internal webchat turns

* Auto-reply tests: cover internal webchat non-routing with external origin metadata

* Changelog: add Control UI iMessage duplicate-reply fix note

* Auto-reply context: track explicit deliver routes

* Gateway chat: mark explicit external deliver routes in context

* Auto-reply: preserve explicit deliver routes for internal webchat turns

* Auto-reply tests: cover explicit deliver routes from internal webchat turns

* Gateway chat tests: assert explicit deliver route context tagging

* fix: enforce 600 perms for cron store and run logs (#36078)

* fix: enforce secure permissions for cron store and run logs

* fix(cron): enforce dir perms and gate posix tests on windows

* Cron store tests: cover existing directory permission hardening

* Cron run-log tests: cover existing directory permission hardening

* Changelog: note cron file permission hardening

---------

Co-authored-by: linhey <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>

* fix(tui): accept canonical session-key aliases in chat event routing

* Gateway: normalize OpenAI stream chunk text

* Gateway: coerce chat deliverable route boolean

* fix(web_search): align brave language codes with API

* Respect source channel for agent event surfacing (#36030)

* fix(session): prefer webchat routes for direct ui turns (#37135)

* Gateway: discriminate input sources

* Cron: migrate legacy provider delivery hints

* Cron: stabilize runs-one-shot migration tests

* fix(memory): retry mcporter after Windows EINVAL spawn

* fix(onboarding): guard daemon status probe on headless linux

* Gateway: add path-scoped config schema lookup (#37266)

Merged via squash.

Prepared head SHA: 0c4d187f6fb66f2799d4047585d6368e433c883a
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* docs(changelog): add pr entry

* fix(ci): restore protocol and schema checks (#37470)

* Fix failover for zhipuai 1310 Weekly/Monthly Limit Exhausted (#33813)

Merged via squash.

Prepared head SHA: 3dc441e58de48913720cf7b6137fa761758d8344
Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* fix(openai-codex-oauth): stop mutating authorize url scopes

* Update CHANGELOG.md

* fix(auth): remove bogus codex oauth responses probe

* docs(changelog): fold codex oauth fix notes

* docs(changelog): add codex oauth pr reference (#37558)

* fix(security:PLA-697): block local secret scratch files from commits

* feat: add dev EKS deployment for openclaw SRE container

* fix: stabilize slack socket mode in dev eks runtime

* fix(eks): reuse monitoring incident auth for openclaw-sre

* feat(deploy): add grafana env guards and prod deploy wrapper

* fix(security): redact tool outputs and enforce secret-safe runtime defaults

* feat(sre): harden heartbeat routing and enrich triage signals

* docs: add SRE hybrid intelligence design

Three-layer architecture to improve bot reasoning quality:
- Layer 1: Service knowledge (auto-discovery + overlays + incident memory)
- Layer 2: Multi-stage reasoning chain (triage → hypothesize → causal chain → action plan → cross-review)
- Layer 3: Incident learning loop (structured cards, overlay suggestions, feedback signals)

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* feat(sandbox): add boundary cli to common runtime image

* docs(sre): finalize hybrid intelligence design v19 after 18 Codex review rounds

Iteratively hardened the design through 18 adversarial Codex review rounds,
resolving 60+ findings (15+ CRITICAL, 45+ HIGH). Key fixes include:
- Decoupled incident_id (pre-Step11 immutable) from card_id (LLM-derived)
- Unified evidence/memory sanitization via shared _strip_instruction_tokens
- Fixed rerun interval default (3600s > heartbeat 1800s) to prevent every-cycle re-runs
- Added Phase 2 cross-review gap note and dual-column depth table
- Overlay suggestion idempotency via deterministic suggestion_key + upsert
- Decoupled chain timeout from legacy budget check
- Added predicate alignment docs for L3 pre-check vs L3 gate
- Adopted dynamic evidence_completeness denominator matching existing code
- Added scope note clarifying design vs current implementation

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* feat(sre): complete hybrid intelligence rollout and bot hardening

* fix(sre): harden slack reasoning, dual chain, and deploy auth/runtime

* ci: add ecr release pipeline and infra-helm image update trigger

* ci: switch workflows to github-hosted runners

* ci: allow manual ecr env target and use updater v4

* ci: remove windows jobs from workflow

* chore(pla-678): update fallback auth fixture and plan docs

* fix(pla-678): preserve control-ui host-header fallback in dev config

* refactor(pla-678): remove local sre chart and require infra-helm

* refactor(pla-678): remove direct eks deploy scripts

* ci(pla-678): remove labeler workflow

* ci(pla-678): refresh checks after disabling labeler

* build: install boundary CLI in SRE runtime image

* fix(slack:PLA-678): keep one thread lane across users

* fix(sre-skill): enforce live db-query runbook in dev seed

* fix(slack): ignore bot thread history when seeding new sessions

* fix(slack): force retry on repeated thread questions

* fix(sre-skill): require retry on repeated db requests

* docs(sre-skill): make retry policy generic across repeated asks

* fix(sre:PLA-678): enforce live linear ticket updates

* fix(sre:PLA-678): use [PLATFORM] Backlog linear project

* fix(sre:PLA-678): label linked linear tickets as openclaw-sre

* fix(sre:PLA-678): auto-label linked linear tickets for auto-pr

* test(sre:PLA-678): make tracking label test executable

* fix(slack:PLA-678): remove status-final completion banner (#16)

* fix(slack:PLA-678): enable direct file attachments from agent replies (#17)

* fix(slack:PLA-678): remove status-final completion banner

* fix(slack): enable direct file attachments from agent replies

* refactor(sre:PLA-678): remove local deploy config mirror (#18)

* fix: compact oversized auto-generated pr bodies

* fix(sre): add built-in linear incident memory provider

* feat(sre): add erpc helper with flo secret query

* fix(sre): enforce canonical rpc.morpho.dev erpc endpoint

* refactor(sre): remove local deploy config mirror

* fix(slack:PLA-678): force DM replies into per-message threads (#19)

* fix: compact oversized auto-generated pr bodies

* fix(sre): add built-in linear incident memory provider

* feat(sre): add erpc helper with flo secret query

* fix(sre): enforce canonical rpc.morpho.dev erpc endpoint

* refactor(sre): remove local deploy config mirror

* fix(slack): force threaded replies for direct messages

* feat(cron:PLA-678): use conversation history in self-improve runs (#20)

* fix(slack:PLA-678): improve progress update readability (#21)

* fix(ci:PLA-678): restore main release pipeline health (#22)

* fix(ci:PLA-678): restore main release pipeline health

* fix(ci:PLA-678): harden auto-response token fallback

* fix(ci:PLA-678): pin setup-bun to published release

* test(ci:PLA-678): align slack thread session expectations

* fix(sre:PLA-678): harden Slack reply delivery and image release flow (#23)

* fix(slack:PLA-678): harden thread-scoped reply delivery

* fix(slack:PLA-678): satisfy lint after rebase

* ci(release:PLA-678): move image release to cached ecr flow

* ci(release:PLA-678): use official docker build actions

* fix(slack:PLA-722): preserve progress updates during final-answer gating (#24)

* fix(sre:PLA-724): restore ECR runtime image toolchain (#25)

* fix(failover): classify HTTP 402 as rate_limit when payload indicates usage limit (#30484) (#36802)

* fix(failover): classify HTTP 402 as rate_limit when payload indicates usage limit (#30484)

Some providers (notably Anthropic Claude Max plan) surface temporary
usage/rate-limit failures as HTTP 402 instead of 429. Before this change,
all 402s were unconditionally mapped to 'billing', which produced a
misleading 'run out of credits' warning for Max plan users who simply
hit their usage window.

This follows the same pattern introduced for HTTP 400 in #36783: check
the error message for an explicit rate-limit signal before falling back
to the default status-code classification.

- classifyFailoverReasonFromHttpStatus now returns 'rate_limit' for 402
  when isRateLimitErrorMessage matches the payload text
- Added regression tests covering both the rate-limit and billing paths
  on 402

* fix: narrow 402 rate-limit matcher to prevent billing misclassification

The original implementation used isRateLimitErrorMessage(), which matches
phrases like 'quota exceeded' that legitimately appear in billing errors.

This commit replaces it with a narrow, 402-specific matcher that requires
BOTH retry language (try again/retry/temporary/cooldown) AND limit
terminology (usage limit/rate limit/organization usage).

Prevents misclassification of errors like:
'HTTP 402: exceeded quota, please add credits' -> billing (not rate_limit)

Added regression test for the ambiguous case.

---------

Co-authored-by: Val Alexander <[email protected]>

* fix(mattermost): allow reachable interaction callback URLs (#37543)

Merged via squash.

Prepared head SHA: 4d593731be5a5dcbf3106d596b38acfeb8cf0aa8
Co-authored-by: mukhtharcm <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* fix(cron:PLA-740): audit previous-day self-improve sessions

---------

Signed-off-by: joshavant <[email protected]>
Co-authored-by: Gustavo Madeira Santana <[email protected]>
Co-authored-by: Mariano <[email protected]>
Co-authored-by: leepokai <[email protected]>
Co-authored-by: Bob <[email protected]>
Co-authored-by: Onur <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: huangcj <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: Sid <[email protected]>
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Co-authored-by: a <[email protected]>
Co-authored-by: echoVic <[email protected]>
Co-authored-by: Shakker <[email protected]>
Co-authored-by: liuxiaopai-ai <[email protected]>
Co-authored-by: Rodrigo Uroz <[email protected]>
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: jalehman <[email protected]>
Co-authored-by: Kai <[email protected]>
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: 青雲 <[email protected]>
Co-authored-by: echoVic <[email protected]>
Co-authored-by: Darshil <[email protected]>
Co-authored-by: Ho Lim <[email protected]>
Co-authored-by: dvrshil <[email protected]>
Co-authored-by: Isis Anisoptera <[email protected]>
Co-authored-by: Madoka <[email protected]>
Co-authored-by: Xu Zimo <[email protected]>
Co-authored-by: Munem Hashmi <[email protected]>
Co-authored-by: bmendonca3 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: Nhj <[email protected]>
Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: rexl2018 <[email protected]>
Co-authored-by: sline <[email protected]>
Co-authored-by: 0xsline <[email protected]>
Co-authored-by: Harold Hunt <[email protected]>
Co-authored-by: Shivam <[email protected]>
Co-authored-by: 不做了睡大觉 <[email protected]>
Co-authored-by: alexyyyander <[email protected]>
Co-authored-by: alexyyyander <[email protected]>
Co-authored-by: Octane0411 <[email protected]>
Co-authored-by: Linux2010 <[email protected]>
Co-authored-by: echoVic <[email protected]>
Co-authored-by: Joseph Turian <[email protected]>
Co-authored-by: turian <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Tony Dehnke <[email protected]>
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: kevinWangSheng <[email protected]>
Co-authored-by: ningding97 <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: clawbie <[email protected]>
Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Ayane <[email protected]>
Co-authored-by: Ayane <[email protected]>
Co-authored-by: StingNing <[email protected]>
Co-authored-by: maweibin <[email protected]>
Co-authored-by: maweibin <[email protected]>
Co-authored-by: Josh Avant <[email protected]>
Co-authored-by: Bin Deng <[email protected]>
Co-authored-by: Byungsker <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Co-authored-by: Altay <[email protected]>
Co-authored-by: jiangnan <[email protected]>
Co-authored-by: jnMetaCode <[email protected]>
Co-authored-by: Jacob Riff <[email protected]>
Co-authored-by: jriff <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: Bill <[email protected]>
Co-authored-by: 2233admin <[email protected]>
Co-authored-by: 2233admin <[email protected]>
Co-authored-by: littleben <[email protected]>
Co-authored-by: littleben <[email protected]>
Co-authored-by: OpenClaw Agent <[email protected]>
Co-authored-by: Vignesh Natarajan <[email protected]>
Co-authored-by: zerone0x <[email protected]>
Co-authored-by: zerone0x <[email protected]>
Co-authored-by: dunamismax <[email protected]>
Co-authored-by: Octane <[email protected]>
Co-authored-by: Mitsuyuki Osabe <[email protected]>
Co-authored-by: Tak <[email protected]>
Co-authored-by: Tyler Yust <[email protected]>
Co-authored-by: Hinata Kaga (samon) <[email protected]>
Co-authored-by: dorukardahan <[email protected]>
Co-authored-by: Tyler Yust <[email protected]>
Co-authored-by: Brenner Spear <[email protected]>
Co-authored-by: aerelune <[email protected]>
Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: Vignesh <[email protected]>
Co-authored-by: OpenClaw SRE Bot <[email protected]>
Co-authored-by: Xinhua Gu <[email protected]>
Co-authored-by: Val Alexander <[email protected]>
0x666c6f added a commit to 0x666c6f/openclaw that referenced this pull request Mar 26, 2026
…openclaw#31)

* Plugins/memory-lancedb: migrate to scoped plugin-sdk imports

* Plugins/minimax-portal-auth: migrate to scoped plugin-sdk imports

* Plugins/msteams: migrate to scoped plugin-sdk imports

* Plugins/nextcloud-talk: migrate to scoped plugin-sdk imports

* Plugins/nostr: migrate to scoped plugin-sdk imports

* Plugins/open-prose: migrate to scoped plugin-sdk imports

* Plugins/phone-control: migrate to scoped plugin-sdk imports

* Plugins/qwen-portal-auth: migrate to scoped plugin-sdk imports

* Plugins/synology-chat: migrate to scoped plugin-sdk imports

* Plugins/talk-voice: migrate to scoped plugin-sdk imports

* Plugins/test-utils: migrate to scoped plugin-sdk imports

* Plugins/thread-ownership: migrate to scoped plugin-sdk imports

* Plugins/tlon: migrate to scoped plugin-sdk imports

* Plugins/twitch: migrate to scoped plugin-sdk imports

* Plugins/voice-call: migrate to scoped plugin-sdk imports

* Plugins/whatsapp: migrate to scoped plugin-sdk imports

* Plugins/zalo: migrate to scoped plugin-sdk imports

* Plugins/zalouser: migrate to scoped plugin-sdk imports

* Chore: remove accidental .DS_Store artifact

* chore(docs): add plugins refactor changelog entry

* feat(ios): add Live Activity connection status + stale cleanup (#33591)

* feat(ios): add live activity connection status and cleanup

Add lock-screen/Dynamic Island connection health states and prune duplicate/stale activities before reuse. This intentionally excludes AI/title generation and heavier UX rewrites from #27488.

Co-authored-by: leepokai <[email protected]>

* fix(ios): treat ended live activities as inactive

* chore(changelog): add PR reference and author thanks

---------

Co-authored-by: leepokai <[email protected]>

* fix: kill stuck ACP child processes on startup and harden sessions in discord threads (#33699)

* Gateway: resolve agent.wait for chat.send runs

* Discord: harden ACP thread binding + listener timeout

* ACPX: handle already-exited child wait

* Gateway/Discord: address PR review findings

* Discord: keep ACP error-state thread bindings on startup

* gateway: make agent.wait dedupe bridge event-driven

* discord: harden ACP probe classification and cap startup fan-out

* discord: add cooperative timeout cancellation

* discord: fix startup probe concurrency helper typing

* plugin-sdk: avoid Windows root-alias shard timeout

* plugin-sdk: keep root alias reflection path non-blocking

* discord+gateway: resolve remaining PR review findings

* gateway+discord: fix codex review regressions

* Discord/Gateway: address Codex review findings

* Gateway: keep agent.wait lifecycle active with shared run IDs

* Discord: clean up status reactions on aborted runs

* fix: add changelog note for ACP/Discord startup hardening (#33699) (thanks @dutifulbob)

---------

Co-authored-by: Onur <[email protected]>

* fix: relay ACP sessions_spawn parent streaming (#34310) (thanks @vincentkoc) (#34310)

Co-authored-by: Onur Solmaz <[email protected]>

* fix(telegram): materialize dm draft final to avoid duplicates

* docs(changelog): credit @Brotherinlaw-13 for #34318

* fix: prevent nodes media base64 context bloat (#34332)

* fix: preserve raw media invoke for HTTP tool clients (#34365)

* fix(slack): route system events to bound agent sessions (#34045)

* fix(slack): route system events via binding-aware session keys

* fix(slack): pass sender to system event session resolver

* fix(slack): include sender context for interaction session routing

* fix(slack): include modal submitter in session routing

* test(slack): cover binding-aware system event routing

* test(slack): update interaction session key assertions

* test(slack): assert reaction session routing carries sender

* docs(changelog): note slack system event routing fix

* Update CHANGELOG.md

* Delete changelog/fragments directory

* fix(memory): serialize local embedding initialization to avoid duplicate model loads (#15639)

Merged via squash.

Prepared head SHA: a085fc21a8ba7163fffdb5de640dd4dc1ff5a88e
Co-authored-by: SubtleSpark <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(model): propagate custom provider headers to model objects (#27490)

Merged via squash.

Prepared head SHA: e4183b398fc7eb4c18b2b691cb0dd882ec993608
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(daemon): handle systemctl is-enabled exit 4 (not-found) on Ubuntu (#33634)

Merged via squash.

Prepared head SHA: 67dffc3ee239cd7b813cb200c3dd5475d9e203a6
Co-authored-by: Yuandiaodiaodiao <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(node-host): sync rawCommand with hardened argv after executable path pinning (#33137)

Merged via squash.

Prepared head SHA: a7987905f7ad6cf5fee286ffa81ceaad8297174f
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* Agents: add generic poll-vote action support

* fix(ollama): pass provider headers to Ollama stream function (#24285)

createOllamaStreamFn() only accepted baseUrl, ignoring custom headers
configured in models.providers.<provider>.headers. This caused 403
errors when Ollama endpoints are behind reverse proxies that require
auth headers (e.g. X-OLLAMA-KEY via HAProxy).

Add optional defaultHeaders parameter to createOllamaStreamFn() and
merge them into every fetch request. Provider headers from config are
now passed through at the call site in the embedded runner.

Fixes #24285

* test(ollama): add default header precedence coverage

* chore(changelog): add PR entry openclaw#24337 thanks @echoVic

* Outbound: allow text-only plugin adapters

* Outbound: avoid empty multi-media fallback sends

* chore(changelog): align outbound adapter entry openclaw#32788 thanks @liuxiaopai-ai

* fix(outbound): fail media-only text-only adapter fallback

* chore(changelog): clarify outbound media-only fallback openclaw#32788 thanks @liuxiaopai-ai

* fix(review): enforce behavioral sweep validation

* Fix gateway restart false timeouts on Debian/systemd (#34874)

* daemon(systemd): target sudo caller user scope

* test(systemd): cover sudo user scope commands

* infra(ports): fall back to ss when lsof missing

* test(ports): verify ss fallback listener detection

* cli(gateway): use probe fallback for restart health

* test(gateway): cover restart-health probe fallback

* Compaction/Safeguard: require structured summary headings (#25555)

Merged via squash.

Prepared head SHA: 0b1df34806a7b788261290be55760fd89220de53
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Fix Linux daemon install checks when systemd user bus env is missing (#34884)

* daemon(systemd): fall back to machine user scope when user bus is missing

* test(systemd): cover machine scope fallback for user-bus errors

* test(systemd): reset execFile mock state across cases

* test(systemd): make machine-user fallback assertion portable

* fix(daemon): keep root sudo path on direct user scope

* test(systemd): cover sudo root user-scope behavior

* ci: use resolvable bun version in setup-node-env

* agents: preserve totalTokens on request failure instead of using contextWindow (#34275)

Merged via squash.

Prepared head SHA: f9d111d0a79a07815d476356e98a28df3a0000ba
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix: align AGENTS.md template section names with post-compaction extraction (#25029) (#25098)

Merged via squash.

Prepared head SHA: 8cd6cc8049aab5a94d8a9d5fb08f2e792c4ac5fd
Co-authored-by: echoVic <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Changelog: add daemon systemd user-bus fallback entry (#34884)

* Changelog: add gateway restart health entry (#34874)

* fix: finalize spanish locale support

* fix: add spanish locale support (#35038) (thanks @DaoPromociones)

* fix(deps): patch hono transitive audit vulnerabilities

* fix(security): avoid prototype-chain account path checks (#34982)

Merged via squash.

Prepared head SHA: f89cc6a649959997fe1dec1e1c1bff9a61b2de98
Co-authored-by: HOYALIM <[email protected]>
Co-authored-by: dvrshil <[email protected]>
Reviewed-by: @dvrshil

* fix(deps): bump tar to 7.5.10

* docs(changelog): document dependency security fixes

* fix: restore auto-reply system events timeline (#34794) (thanks @anisoptera) (#34794)

Co-authored-by: Ayaan Zaidi <[email protected]>

* fix(feishu): comprehensive reply mechanism — outbound replyToId forwarding + topic-aware reply targeting (#33789)

* fix(feishu): comprehensive reply mechanism fix — outbound replyToId forwarding + topic-aware reply targeting

- Forward replyToId from ChannelOutboundContext through sendText/sendMedia
  to sendMessageFeishu/sendMarkdownCardFeishu/sendMediaFeishu, enabling
  reply-to-message via the message tool.

- Fix group reply targeting: use ctx.messageId (triggering message) in
  normal groups to prevent silent topic thread creation (#32980). Preserve
  ctx.rootId targeting for topic-mode groups (group_topic/group_topic_sender)
  and groups with explicit replyInThread config.

- Add regression tests for both fixes.

Fixes #32980
Fixes #32958
Related #19784

* fix: normalize Feishu delivery.to before comparing with messaging tool targets

- Add normalizeDeliveryTarget helper to strip user:/chat: prefixes for Feishu
- Apply normalization in matchesMessagingToolDeliveryTarget before comparison
- This ensures cron duplicate suppression works when session uses prefixed targets
  (user:ou_xxx) but messaging tool extract uses normalized bare IDs (ou_xxx)

Fixes review comment on PR #32755

(cherry picked from commit fc20106f16ccc88a5f02e58922bb7b7999fe9dcd)

* fix(feishu): catch thrown SDK errors for withdrawn reply targets

The Feishu Lark SDK can throw exceptions (SDK errors with .code or
AxiosErrors with .response.data.code) for withdrawn/deleted reply
targets, in addition to returning error codes in the response object.

Wrap reply calls in sendMessageFeishu and sendCardFeishu with
try-catch to handle thrown withdrawn/not-found errors (230011,
231003) and fall back to client.im.message.create, matching the
existing response-level fallback behavior.

Also extract sendFallbackDirect helper to deduplicate the
direct-send fallback block across both functions.

Closes #33496

(cherry picked from commit ad0901aec103a2c52f186686cfaf5f8ba54b4a48)

* feishu: forward outbound reply target context

(cherry picked from commit c129a691fcf552a1cebe1e8a22ea8611ffc3b377)

* feishu extension: tighten reply target fallback semantics

(cherry picked from commit f85ec610f267020b66713c09e648ec004b2e26f1)

* fix(feishu): align synthesized fallback typing and changelog attribution

* test(feishu): cover group_topic_sender reply targeting

---------

Co-authored-by: Xu Zimo <[email protected]>
Co-authored-by: Munem Hashmi <[email protected]>
Co-authored-by: bmendonca3 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(feishu): use msg_type media for mp4 video (fixes #33674) (#33720)

* fix(feishu): use msg_type media for mp4 video (fixes #33674)

* Feishu: harden streaming merge semantics and final reply dedupe

Use explicit streaming update semantics in the Feishu reply dispatcher:
treat onPartialReply payloads as snapshot updates and block fallback payloads
as delta chunks, then merge final text with the shared overlap-aware
mergeStreamingText helper before closing the stream.

Prevent duplicate final text delivery within the same dispatch cycle, and add
regression tests covering overlap snapshot merge, duplicate final suppression,
and block-as-delta behavior to guard against repeated/truncated output.

* fix(feishu): prefer message.reply for streaming cards in topic threads

* fix: reduce Feishu streaming card print_step to avoid duplicate rendering

Fixes openclaw/openclaw#33751

* Feishu: preserve media sends on duplicate finals and add media synthesis changelog

* Feishu: only dedupe exact duplicate final replies

* Feishu: use scoped plugin-sdk import in streaming-card tests

---------

Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(agents): bypass pendingDescendantRuns guard for cron announce delivery (#35185)

* fix(agents): bypass pendingDescendantRuns guard for cron announce delivery

Standalone cron job completions were blocked from direct channel delivery
when the cron run had spawned subagents that were still registered as
pending. The pendingDescendantRuns guard exists for live orchestration
coordination and should not apply to fire-and-forget cron announce sends.

Thread the announceType through the delivery chain and skip both the
child-descendant and requester-descendant pending-run guards when the
announce originates from a cron job.

Closes #34966

* fix: ensure outbound session entry for cron announce with named agents (#32432)

Named agents may not have a session entry for their delivery target,
causing the announce flow to silently fail (delivered=false, no error).

Two fixes:
1. Call ensureOutboundSessionEntry when resolving the cron announce
   session key so downstream delivery can find channel metadata.
2. Fall back to direct outbound delivery when announce delivery fails
   to ensure cron output reaches the target channel.

Closes #32432

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: guard announce direct-delivery fallback against suppression leaks (#32432)

The `!delivered` fallback condition was too broad — it caught intentional
suppressions (active subagents, interim messages, SILENT_REPLY_TOKEN) in
addition to actual announce delivery failures.  Add an
`announceDeliveryWasAttempted` flag so the direct-delivery fallback only
fires when `runSubagentAnnounceFlow` was actually called and failed.

Also remove the redundant `if (route)` guard in
`resolveCronAnnounceSessionKey` since `resolved` being truthy guarantees
`route` is non-null.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix(cron): harden announce synthesis follow-ups

---------

Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* Feishu: harden streaming merge semantics and final reply dedupe (#33245)

* Feishu: close duplicate final gap and cover routing precedence

* Feishu: resolve reviewer duplicate-final and routing feedback

* Feishu: tighten streaming send-mode option typing

* Feishu: fix reverse-overlap streaming merge ordering

* Feishu: align streaming final dedupe test expectation

* Feishu: allow distinct streaming finals while deduping repeats

---------

Co-authored-by: Tak Hoffman <[email protected]>

* fix: cron backup should preserve pre-edit snapshot (#35195) (#35234)

* fix(cron): avoid overwriting .bak during normalization

Fixes openclaw/openclaw#35195

* test(cron): preserve pre-edit bak snapshot in normalization path

---------

Co-authored-by: 0xsline <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(cron): stabilize restart catch-up replay semantics (#35351)

* Cron: stabilize restart catch-up replay semantics

* Cron: respect backoff in startup missed-run replay

* cron: narrow startup replay backoff guard (#35391)

* cron: unify stale-run recovery and preserve manual-run every anchors (#35363)

* cron: unify stale-run recovery and preserve manual every anchors

* cron: address unresolved review threads on recovery paths

* cron: remove duplicate timestamp helper after rebase

* refactor(telegram): remove unused webhook callback helper (#27816)

* fix(pr): make review claim step required

* fix(skills): deduplicate slash commands by skillName across all interfaces

Move skill-command deduplication by skillName from the Discord-only
`dedupeSkillCommandsForDiscord` into `listSkillCommandsForAgents` so
every interface (TUI, Slack, text) consistently sees a clean command
list without platform-specific workarounds.

When multiple agents share a skill with the same name the old code
emitted `github` + `github_2` and relied on Discord to collapse them.
Now `listSkillCommandsForAgents` returns only the first registration
per skillName, and the Discord-specific wrapper is removed.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* style: fix formatting in skill-commands.test.ts and provider.ts

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>

* style(skills): align formatting cleanup for dedupe changes

* chore(changelog): add dedupe note openclaw#27521 thanks @shivama205

* fix(agents): detect Venice provider proxying xAI/Grok models for schema cleaning (#35355)

Merged via squash.

Prepared head SHA: 8bfdec257bb6a6025cb69a0a213a433da32b15db
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(agents): decode HTML entities in xAI/Grok tool call arguments (#35276)

Merged via squash.

Prepared head SHA: c4445d2938898ded9c046614f9315dbda65ec573
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(agents): guard promoteThinkingTagsToBlocks against malformed content entries (#35143)

Merged via squash.

Prepared head SHA: 3971122f5fd27c66c8c9c5ce783f00e113b1f47b
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(web-ui): render Accounts schema node properly (#35380)

Co-authored-by: stakeswky <[email protected]>
Co-authored-by: liuxiaopai-ai <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(agents): guard context pruning against malformed thinking blocks (#35146)

Merged via squash.

Prepared head SHA: a196a565b1b8e806ffbf85172bcf1128796b45a2
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* fix(gateway): prevent internal route leakage in chat.send

Synthesis of routing fixes from #35321, #34635, and #35356 for internal-client reply safety.

- Require explicit `deliver: true` before inheriting any external delivery route.
- Keep webchat/TUI/UI-origin traffic on internal routing by default.
- Allow configured-main session inheritance only for non-Webchat/UI clients, and honor `session.mainKey`.
- Add regression tests for UI no-inherit, configured-main CLI inherit, and deliver-flag behavior.

Co-authored-by: alexyyyander <[email protected]>
Co-authored-by: Octane0411 <[email protected]>
Co-authored-by: Linux2010 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(gateway): pass actual version to Control UI client instead of dev (#35230)

* fix(gateway): pass actual version to Control UI client instead of "dev"

The GatewayClient, CLI WS client, and browser Control UI all sent
"dev" as their clientVersion during handshake, making it impossible
to distinguish builds in gateway logs and health snapshots.

- GatewayClient and CLI WS client now use the resolved VERSION constant
- Control UI reads serverVersion from the bootstrap endpoint and
  forwards it when connecting
- Bootstrap contract extended with serverVersion field

Closes #35209

* Gateway: fix control-ui version version-reporting consistency

* Control UI: guard deferred bootstrap connect after disconnect

* fix(ui): accept same-origin http and relative gateway URLs for client version

---------

Co-authored-by: Tak Hoffman <[email protected]>

* chore(pr): enforce changelog placement and reduce merge sync churn

* TTS: add baseUrl support to OpenAI TTS config (#34321)

Merged via squash.

Prepared head SHA: e9a10cf81d2021cf81091dfa81e13ffdbb6a540a
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Reviewed-by: @shakkernerd

* ACP: add persistent Discord channel and Telegram topic bindings (#34873)

* docs: add ACP persistent binding experiment plan

* docs: align ACP persistent binding spec to channel-local config

* docs: scope Telegram ACP bindings to forum topics only

* docs: lock bound /new and /reset behavior to in-place ACP reset

* ACP: add persistent discord/telegram conversation bindings

* ACP: fix persistent binding reuse and discord thread parent context

* docs: document channel-specific persistent ACP bindings

* ACP: split persistent bindings and share conversation id helpers

* ACP: defer configured binding init until preflight passes

* ACP: fix discord thread parent fallback and explicit disable inheritance

* ACP: keep bound /new and /reset in-place

* ACP: honor configured bindings in native command flows

* ACP: avoid configured fallback after runtime bind failure

* docs: refine ACP bindings experiment config examples

* acp: cut over to typed top-level persistent bindings

* ACP bindings: harden reset recovery and native command auth

* Docs: add ACP bound command auth proposal

* Tests: normalize i18n registry zh-CN assertion encoding

* ACP bindings: address review findings for reset and fallback routing

* ACP reset: gate hooks on success and preserve /new arguments

* ACP bindings: fix auth and binding-priority review findings

* Telegram ACP: gate ensure on auth and accepted messages

* ACP bindings: fix session-key precedence and unavailable handling

* ACP reset/native commands: honor fallback targets and abort on bootstrap failure

* Config schema: validate ACP binding channel and Telegram topic IDs

* Discord ACP: apply configured DM bindings to native commands

* ACP reset tails: dispatch through ACP after command handling

* ACP tails/native reset auth: fix target dispatch and restore full auth

* ACP reset detection: fallback to active ACP keys for DM contexts

* Tests: type runTurn mock input in ACP dispatch test

* ACP: dedup binding route bootstrap and reset target resolution

* reply: align ACP reset hooks with bound session key

* docs: replace personal discord ids with placeholders

* fix: add changelog entry for ACP persistent bindings (#34873) (thanks @dutifulbob)

---------

Co-authored-by: Onur <[email protected]>

* docs(telegram): recommend allowlist for single-user DM policy (#34841)

* docs(telegram): recommend allowlist for single-user bots

* docs(telegram): condense single-user allowlist note

---------

Co-authored-by: echoVic <[email protected]>

* fix(feishu): check response.ok before calling response.json() in streaming card (#35628)

Merged via squash.

Prepared head SHA: 62c3fec80d97cea9be344c0bef5358a0a5dc5560
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* Mattermost: honor onmessage mention override and add gating diagnostics tests (#27160)

Merged via squash.

Prepared head SHA: 6cefb1d5bf3d6dfcec36c1cee3f9ea887f10c890
Co-authored-by: turian <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* fix(subagents): strip leaked [[reply_to]] tags from completion announces (#34503)

* fix(subagents): strip reply tags from completion delivery text

* test(subagents): cover reply-tag stripping in cron completion sends

* changelog: note iMessage reply-tag stripping in completion announces

* Update CHANGELOG.md

* Apply suggestion from @greptile-apps[bot]

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

---------

Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>

* fix(cron): restore direct fallback after announce failure in best-effort mode (openclaw#36177)

Verified:
- pnpm build
- pnpm check (fails on pre-existing origin/main lint debt in extensions/mattermost imports)
- pnpm test:macmini

Co-authored-by: Tak Hoffman <[email protected]>

* test(cron): add cross-channel announce fallback regression coverage (openclaw#36197)

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check (fails on pre-existing origin/main lint debt in extensions/mattermost imports)
- pnpm test:macmini

Co-authored-by: Tak Hoffman <[email protected]>

* feat(mattermost): add interactive buttons support (#19957)

Merged via squash.

Prepared head SHA: 8a25e608729d0b9fd07bb0ee4219d199d9796dbe
Co-authored-by: tonydehnke <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* fix(browser): remove deprecated --disable-blink-features=AutomationControlled flag

- Removes OpenClaw's default `--disable-blink-features=AutomationControlled` Chrome launch switch to avoid unsupported-flag warnings in newer Chrome (#35721).
- Preserves compatibility for older Chrome via `browser.extraArgs` override behavior (source analysis: #35770, #35728, #35727, #35885).
- Synthesis attribution: thanks @Sid-Qin, @kevinWangSheng, @ningding97, @Naylenv, @clawbie.

Source PR refs: #35734, #35770, #35728, #35727, #35885

Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: kevinWangSheng <[email protected]>
Co-authored-by: ningding97 <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: clawbie <[email protected]>
Co-authored-by: Takhoffman <[email protected]>

* fix(feishu): add HTTP timeout to prevent per-chat queue deadlocks (#36430)

When the Feishu API hangs or responds slowly, the sendChain never settles,
causing the per-chat queue to remain in a processing state forever and
blocking all subsequent messages in that thread. This adds a 30-second
default timeout to all Feishu HTTP requests by providing a timeout-aware
httpInstance to the Lark SDK client.

Closes #36412

Co-authored-by: Ayane <[email protected]>

* fix(feishu): use probed botName for mention checks (#36391)

* Feishu: honor bot mentions by ID despite aliases (Fixes #36317) (#36333)

* Mattermost: switch plugin-sdk imports to scoped subpaths (openclaw#36480)

Verified:
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(feishu): accept groupPolicy "allowall" as alias for "open" (#36358)

* fix(feishu): accept groupPolicy "allowall" as alias for "open"

When users configure groupPolicy: "allowall" in Feishu channel config,
the Zod schema rejects the value and the runtime policy check falls
through to the allowlist path.  With an empty allowFrom array, all group
messages are silently dropped despite the intended "allow all" semantics.

Accept "allowall" at the schema level (transform to "open") and add a
runtime guard in isFeishuGroupAllowed so the value is handled even if it
bypasses schema validation.

Closes #36312

Made-with: Cursor

* Feishu: tighten allowall alias handling and coverage

---------

Co-authored-by: Tak Hoffman <[email protected]>

* synthesis: fix Feishu group mention slash parsing

## Summary\n\nFeishu group slash command parsing is fixed for mentions and command probes across authorization paths.\n\nThis includes:\n- Normalizing bot mention text in group context for reliable slash detection in message parsing.\n- Adding command-probe normalization for group slash invocations.\n\nCo-authored-by: Sid Qin <[email protected]>\nCo-authored-by: Tak Hoffman <[email protected]>

* Feishu: normalize group slash command probing

- Feishu/group slash command detection: normalize group mention wrappers before command-authorization probing so mention-prefixed commands are recognized in group routing.\n- Source PR: #36011\n- Contributor: @liuxiaopai-ai\n\nCo-authored-by: Tak Hoffman <[email protected]>\nCo-authored-by: liuxiaopai-ai <[email protected]>

* add prependSystemContext and appendSystemContext to before_prompt_build (fixes #35131) (#35177)

Merged via squash.

Prepared head SHA: d9a2869ad69db9449336a2e2846bd9de0e647ac6
Co-authored-by: maweibin <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(feishu): avoid media regressions from global HTTP timeout (#36500)

* fix(feishu): avoid media regressions from global http timeout

* fix(feishu): source HTTP timeout from config

* fix(feishu): apply media timeout override to image uploads

* fix(feishu): invalidate cached client when timeout changes

* fix(feishu): clamp timeout values and cover image download

* Gateway: add SecretRef support for gateway.auth.token with auth-mode guardrails (#35094)

* fix(embedded): classify model_context_window_exceeded as context overflow, trigger compaction (#35934)

Merged via squash.

Prepared head SHA: 20fa77289c80b2807a6779a3df70440242bc18ca
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(agents): skip compaction API call when session has no real messages (#36451)

Merged via squash.

Prepared head SHA: 52dd6317895c7bd10855d2bd7dbbfc2f5279b68e
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(ui): catch marked.js parse errors to prevent Control UI crash (#36445)

- Prevent Control UI session render crashes when `marked.parse()` encounters pathological recursive markdown by safely falling back to escaped `<pre>` output.
- Tighten markdown fallback regression coverage and keep changelog attribution in sync for this crash-hardening path.

Co-authored-by: Bin Deng <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(session): archive old transcript on daily/scheduled reset to prevent orphaned files (#35493)

Merged via squash.

Prepared head SHA: 0d95549d752adecfc0b08d5cd55a8b8c75e264fe
Co-authored-by: byungsker <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(agents): set preserveSignatures to isAnthropic in resolveTranscriptPolicy (#32813)

Merged via squash.

Prepared head SHA: f522d21ca59a42abac554435a0aa646f6a34698d
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix: avoid false global rate-limit classification from generic cooldown text (#32972)

Merged via squash.

Prepared head SHA: 813c16f5afce415da130a917d9ce9f968912b477
Co-authored-by: stakeswky <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* refactor(agents): share failover HTTP status classification (#36615)

* fix(agents): classify transient failover statuses consistently

* fix(agents): preserve legacy failover status mapping

* fix(failover): narrow service-unavailable to require overload indicator (#32828) (#36646)

Merged via squash.

Prepared head SHA: 46fb4306127972d7635f371fd9029fbb9baff236
Co-authored-by: jnMetaCode <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* Compaction/Safeguard: add summary quality audit retries (#25556)

Merged via squash.

Prepared head SHA: be473efd1635616ebbae6e649d542ed50b4a827f
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* test(agents): add provider-backed failover regressions (#36735)

* test(agents): add provider-backed failover fixtures

* test(agents): cover more provider error docs

* test(agents): tighten provider doc fixtures

* Docs: add Slack typing reaction fallback

* Docs: update gateway config reference for Slack and TTS

* Docs: clarify OpenAI-compatible TTS endpoints

* Docs: document Control UI locale support

* Docs: cover heartbeat, cron, and plugin route updates

* fix(ui): bump dompurify to 3.3.2 (#36781)

* UI: bump dompurify to 3.3.2

* Deps: refresh dompurify lockfile

* UI: hoist lifecycle connect test mocks (#36788)

* fix(agents): classify insufficient_quota 400s as billing (#36783)

* feat: append UTC time alongside local time in shared Current time lines (#32423)

Merged via squash.

Prepared head SHA: 9e8ec13933b5317e7cff3f0bc048de515826c31a
Co-authored-by: jriff <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* fix(auth): grant senderIsOwner for internal channels with operator.admin scope (openclaw#35704)

Verified:
- pnpm install --frozen-lockfile
- pnpm build
- pnpm check
- pnpm test:macmini

Co-authored-by: Naylenv <[email protected]>
Co-authored-by: Octane0411 <[email protected]>
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(config): prevent RangeError in merged schema cache key generation

Fix merged schema cache key generation for high-cardinality plugin/channel metadata by hashing incrementally instead of serializing one large aggregate string.

Includes changelog entry for the user-visible regression fix.

Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: Bill <[email protected]>

* fix(slack): propagate mediaLocalRoots through Slack send path

Restore Slack local file upload parity with CVE-era local media allowlist enforcement by threading `mediaLocalRoots` through the Slack send call chain.

- pass `ctx.mediaLocalRoots` from Slack channel action adapter into `handleSlackAction`
- add and forward `mediaLocalRoots` in Slack action context/send path
- pass `mediaLocalRoots` into `sendMessageSlack` for upload allowlist enforcement
- add changelog entry with attribution for this behavior fix

Co-authored-by: 2233admin <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(slack): preserve dedupe while recovering dropped app_mention (#34937)

This PR fixes Slack mention loss without reintroducing duplicate dispatches.

- Preserve seen-message dedupe at ingress to prevent duplicate processing.
- Allow a one-time app_mention retry only when the paired message event was previously dropped before dispatch.
- Add targeted race tests for both recovery and duplicate-prevention paths.

Co-authored-by: littleben <[email protected]>
Co-authored-by: OpenClaw Agent <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* README: add algal to contributors list (#2046)

* fix: decouple Discord inbound worker timeout from listener timeout (#36602) (thanks @dutifulbob) (#36602)

Co-authored-by: Onur Solmaz <[email protected]>

* plugins: enforce prompt hook policy with runtime validation (#36567)

Merged via squash.

Prepared head SHA: 6b9d883b6ae33628235fb02ce39c0d0f46a065bb
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(memory): avoid destructive qmd collection rebinds

* Harden Telegram poll gating and schema consistency (#36547)

Merged via squash.

Prepared head SHA: f77824419e3d166f727474a9953a063a2b4547f2
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(browser): close tracked tabs on session cleanup (#36666)

* Diffs: restore system prompt guidance (#36904)

Merged via squash.

Prepared head SHA: 1b3be3c87957c068473d5c86b9efba4a1a8503f2
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* fix(routing): avoid full binding rescans in resolveAgentRoute (#36915)

* fix(gateway): honor insecure ws override for remote hostnames

* fix(llm-task): load runEmbeddedPiAgent from dist/extensionAPI in installs

* fix(auth): harden openai-codex oauth login path

* feat(telegram/acp): Topic Binding, Pin Binding Message, Fix Spawn Param Parsing (#36683)

* fix(acp): normalize unicode flags and Telegram topic binding

* feat(telegram/acp): restore topic-bound ACP and session bindings

* fix(acpx): clarify permission-denied guidance

* feat(telegram/acp): pin spawn bind notice in topics

* docs(telegram): document ACP topic thread binding behavior

* refactor(reply): share Telegram conversation-id resolver

* fix(telegram/acp): preserve bound session routing semantics

* fix(telegram): respect binding persistence and expiry reporting

* refactor(telegram): simplify binding lifecycle persistence

* fix(telegram): bind acp spawns in direct messages

* fix: document telegram ACP topic binding changelog (#36683) (thanks @huntharo)

---------

Co-authored-by: Onur <[email protected]>

* fix(gateway): preserve streamed prefixes across tool boundaries

* fix(tui): prevent stale model indicator after /model

* Memory: handle SecretRef keys in doctor embeddings (#36835)

Merged via squash.

Prepared head SHA: c1a3d0caae60115d886e8bfc9983c9533c773f04
Co-authored-by: joshavant <[email protected]>
Co-authored-by: joshavant <[email protected]>
Reviewed-by: @joshavant

* fix(openai-codex): request required oauth api scopes (#24720)

* fix(memory-flush): ban timestamped variant files in default flush prompt (#34951)

Merged via squash.

Prepared head SHA: efadda4988b460e6da07be72994d4951d64239d0
Co-authored-by: zerone0x <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(tui): render final event error when assistant output is empty (#14687)

* feat(agents): flush reply pipeline before compaction wait (#35489)

Merged via squash.

Prepared head SHA: 7dbbcc510b74b0e8d35eb750d24575e34b5d769a
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: jalehman <[email protected]>
Reviewed-by: @jalehman

* fix(secrets): harden api key normalization for ByteString headers

* fix(slack): remove double mrkdwn conversion in native streaming path

Remove redundant text normalization from Slack native streaming markdown_text flow so Markdown formatting is preserved.

Synthesis context: overlaps reviewed from #34931, #34759, #34716, #34682, #34814.

Co-authored-by: littleben <[email protected]>
Co-authored-by: dunamismax <[email protected]>
Co-authored-by: Octane <[email protected]>
Co-authored-by: Mitsuyuki Osabe <[email protected]>
Co-authored-by: Kai <[email protected]>
Co-authored-by: OpenClaw Agent <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>

* fix(kimi-coding): normalize anthropic tool payload format

* fix(slack): thread channel ID through inbound context for reactions (#34831)

Slack reaction/thread context routing fixes via canonical synthesis of #34831.

Co-authored-by: Tak <[email protected]>

* fix(heartbeat): pin HEARTBEAT.md reads to workspace path

* fix(subagents): recover announce cleanup after kill/complete race

* feat(hooks): emit compaction lifecycle hooks (#16788)

* fix(auth): harden openai-codex oauth refresh fallback

* fix(subagents): announce delivery with descendant gating, frozen result refresh, and cron retry (#35080)

Thanks @tyler6204

* fix(agents): avoid synthetic tool-result writes on idle-timeout cleanup

* fix(agent): harden undici stream timeouts for long openai-completions runs

* fix(slack): record app_mention retry key before dedupe check (#37033)

- Prime app_mention retry allowance before dedupe so near-simultaneous message/app_mention races do not drop valid mentions.
- Prevent duplicate dispatch when app_mention wins the race and message prepare later succeeds.
- Prune dispatched mention keys and add regression coverage for both dropped and successful in-flight message outcomes.

Co-authored-by: Tak Hoffman <[email protected]>

* fix(agents): honor explicit rate-limit cooldown probes in fallback runs

* fix(agents): allow configured ollama endpoints without dummy api keys

* fix(memory): recover qmd updates from duplicate document constraints

* Doctor: warn on implicit heartbeat directPolicy (#36789)

* Changelog: note heartbeat directPolicy doctor warning

* Tests: cover heartbeat directPolicy doctor warning

* Doctor: warn on implicit heartbeat directPolicy

* Tests: cover per-agent heartbeat directPolicy warning

* Update CHANGELOG.md

* Plugins: clarify registerHttpHandler migration errors (#36794)

* Changelog: note plugin HTTP route migration diagnostics

* Tests: cover registerHttpHandler migration diagnostics

* Plugins: clarify registerHttpHandler migration errors

* Tests: cover registerHttpHandler diagnostic edge cases

* Plugins: tighten registerHttpHandler migration hint

* fix(memory): repair qmd collection name conflicts during ensure

* fix(memory): handle qmd search results without docid

* Plugins: avoid false integrity drift prompts on unpinned updates (#37179)

* Plugins: skip drift prompts for unpinned updates

* Plugins: cover unpinned integrity update behavior

* Changelog: add #37179 release note

* Delete changelog/fragments directory

* Update CHANGELOG.md

* fix(whatsapp): remove implicit [openclaw] self-chat prefix

* fix: remove config.schema from agent gateway tool (#7382)

Merged via squash.

Prepared head SHA: f34a7780690a941936b31899e2d096b8a07f4afc
Co-authored-by: kakuteki <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* feat(openai): add gpt-5.4 support for API and Codex OAuth (#36590)

* feat(openai): add gpt-5.4 support and priority processing

* feat(openai-codex): add gpt-5.4 oauth support

* fix(openai): preserve provider overrides in gpt-5.4 fallback

* fix(openai-codex): keep xhigh for gpt-5.4 default

* fix(models): preserve configured overrides in list output

* fix(models): close gpt-5.4 integration gaps

* fix(openai): scope service tier to public api

* fix(openai): complete prep followups for gpt-5.4 support (#36590) (thanks @dorukardahan)

---------

Co-authored-by: Tyler Yust <[email protected]>

* fix(tui): preserve credential-like tokens in render sanitization

* CLI: make read-only SecretRef status flows degrade safely (#37023)

* CLI: add read-only SecretRef inspection

* CLI: fix read-only SecretRef status regressions

* CLI: preserve read-only SecretRef status fallbacks

* Docs: document read-only channel inspection hook

* CLI: preserve audit coverage for read-only SecretRefs

* CLI: fix read-only status account selection

* CLI: fix targeted gateway fallback analysis

* CLI: fix Slack HTTP read-only inspection

* CLI: align audit credential status checks

* CLI: restore Telegram read-only fallback semantics

* chore(changelog): update for #37023

Signed-off-by: joshavant <[email protected]>

* fix(agents): disable usage streaming chunks on non-native openai-completions

* feat(nano-banana-pro): add --aspect-ratio flag to generate_image.py (#28159)

* feat(nano-banana-pro): add --aspect-ratio flag to generate_image.py

* Nano Banana: allow all supported aspect ratios

* Docs: expand nano banana aspect ratio options

---------

Co-authored-by: Vincent Koc <[email protected]>

* fix(gateway): support image_url in OpenAI chat completions (#34068)

* fix(gateway): parse image_url in openai chat completions

* test(gateway): cover openai chat completions image_url flows

* docs(changelog): note openai image_url chat completions fix (#17685)

* fix(gateway): harden openai image_url parsing and limits

* test(gateway): add openai image_url regression coverage

* docs(changelog): expand #17685 openai chat completions note

* Gateway: make OpenAI image_url URL fetch opt-in and configurable

* Diagnostics: redact image base64 payload data in trace logs

* Changelog: note OpenAI image_url hardening follow-ups

* Gateway: enforce OpenAI image_url total budget incrementally

* Gateway: scope OpenAI image_url extraction to the active turn

* Update CHANGELOG.md

* fix(agents): avoid xAI web_search tool-name collisions

* fix: clear Telegram DM draft after materialize (#36746) (thanks @joelnishanth)

* Fix Control UI duplicate iMessage replies for internal webchat turns (#36151)

* Auto-reply: avoid routing external replies from internal webchat turns

* Auto-reply tests: cover internal webchat non-routing with external origin metadata

* Changelog: add Control UI iMessage duplicate-reply fix note

* Auto-reply context: track explicit deliver routes

* Gateway chat: mark explicit external deliver routes in context

* Auto-reply: preserve explicit deliver routes for internal webchat turns

* Auto-reply tests: cover explicit deliver routes from internal webchat turns

* Gateway chat tests: assert explicit deliver route context tagging

* fix: enforce 600 perms for cron store and run logs (#36078)

* fix: enforce secure permissions for cron store and run logs

* fix(cron): enforce dir perms and gate posix tests on windows

* Cron store tests: cover existing directory permission hardening

* Cron run-log tests: cover existing directory permission hardening

* Changelog: note cron file permission hardening

---------

Co-authored-by: linhey <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>

* fix(tui): accept canonical session-key aliases in chat event routing

* Gateway: normalize OpenAI stream chunk text

* Gateway: coerce chat deliverable route boolean

* fix(web_search): align brave language codes with API

* Respect source channel for agent event surfacing (#36030)

* fix(session): prefer webchat routes for direct ui turns (#37135)

* Gateway: discriminate input sources

* Cron: migrate legacy provider delivery hints

* Cron: stabilize runs-one-shot migration tests

* fix(memory): retry mcporter after Windows EINVAL spawn

* fix(onboarding): guard daemon status probe on headless linux

* Gateway: add path-scoped config schema lookup (#37266)

Merged via squash.

Prepared head SHA: 0c4d187f6fb66f2799d4047585d6368e433c883a
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Reviewed-by: @gumadeiras

* docs(changelog): add pr entry

* fix(ci): restore protocol and schema checks (#37470)

* Fix failover for zhipuai 1310 Weekly/Monthly Limit Exhausted (#33813)

Merged via squash.

Prepared head SHA: 3dc441e58de48913720cf7b6137fa761758d8344
Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* fix(openai-codex-oauth): stop mutating authorize url scopes

* Update CHANGELOG.md

* fix(auth): remove bogus codex oauth responses probe

* docs(changelog): fold codex oauth fix notes

* docs(changelog): add codex oauth pr reference (#37558)

* fix(security:PLA-697): block local secret scratch files from commits

* feat: add dev EKS deployment for openclaw SRE container

* fix: stabilize slack socket mode in dev eks runtime

* fix(eks): reuse monitoring incident auth for openclaw-sre

* feat(deploy): add grafana env guards and prod deploy wrapper

* fix(security): redact tool outputs and enforce secret-safe runtime defaults

* feat(sre): harden heartbeat routing and enrich triage signals

* docs: add SRE hybrid intelligence design

Three-layer architecture to improve bot reasoning quality:
- Layer 1: Service knowledge (auto-discovery + overlays + incident memory)
- Layer 2: Multi-stage reasoning chain (triage → hypothesize → causal chain → action plan → cross-review)
- Layer 3: Incident learning loop (structured cards, overlay suggestions, feedback signals)

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* feat(sandbox): add boundary cli to common runtime image

* docs(sre): finalize hybrid intelligence design v19 after 18 Codex review rounds

Iteratively hardened the design through 18 adversarial Codex review rounds,
resolving 60+ findings (15+ CRITICAL, 45+ HIGH). Key fixes include:
- Decoupled incident_id (pre-Step11 immutable) from card_id (LLM-derived)
- Unified evidence/memory sanitization via shared _strip_instruction_tokens
- Fixed rerun interval default (3600s > heartbeat 1800s) to prevent every-cycle re-runs
- Added Phase 2 cross-review gap note and dual-column depth table
- Overlay suggestion idempotency via deterministic suggestion_key + upsert
- Decoupled chain timeout from legacy budget check
- Added predicate alignment docs for L3 pre-check vs L3 gate
- Adopted dynamic evidence_completeness denominator matching existing code
- Added scope note clarifying design vs current implementation

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* feat(sre): complete hybrid intelligence rollout and bot hardening

* fix(sre): harden slack reasoning, dual chain, and deploy auth/runtime

* ci: add ecr release pipeline and infra-helm image update trigger

* ci: switch workflows to github-hosted runners

* ci: allow manual ecr env target and use updater v4

* ci: remove windows jobs from workflow

* chore(pla-678): update fallback auth fixture and plan docs

* fix(pla-678): preserve control-ui host-header fallback in dev config

* refactor(pla-678): remove local sre chart and require infra-helm

* refactor(pla-678): remove direct eks deploy scripts

* ci(pla-678): remove labeler workflow

* ci(pla-678): refresh checks after disabling labeler

* build: install boundary CLI in SRE runtime image

* fix(slack:PLA-678): keep one thread lane across users

* fix(sre-skill): enforce live db-query runbook in dev seed

* fix(slack): ignore bot thread history when seeding new sessions

* fix(slack): force retry on repeated thread questions

* fix(sre-skill): require retry on repeated db requests

* docs(sre-skill): make retry policy generic across repeated asks

* fix(sre:PLA-678): enforce live linear ticket updates

* fix(sre:PLA-678): use [PLATFORM] Backlog linear project

* fix(sre:PLA-678): label linked linear tickets as openclaw-sre

* fix(sre:PLA-678): auto-label linked linear tickets for auto-pr

* test(sre:PLA-678): make tracking label test executable

* fix(slack:PLA-678): remove status-final completion banner (#16)

* fix(slack:PLA-678): enable direct file attachments from agent replies (#17)

* fix(slack:PLA-678): remove status-final completion banner

* fix(slack): enable direct file attachments from agent replies

* refactor(sre:PLA-678): remove local deploy config mirror (#18)

* fix: compact oversized auto-generated pr bodies

* fix(sre): add built-in linear incident memory provider

* feat(sre): add erpc helper with flo secret query

* fix(sre): enforce canonical rpc.morpho.dev erpc endpoint

* refactor(sre): remove local deploy config mirror

* fix(slack:PLA-678): force DM replies into per-message threads (#19)

* fix: compact oversized auto-generated pr bodies

* fix(sre): add built-in linear incident memory provider

* feat(sre): add erpc helper with flo secret query

* fix(sre): enforce canonical rpc.morpho.dev erpc endpoint

* refactor(sre): remove local deploy config mirror

* fix(slack): force threaded replies for direct messages

* feat(cron:PLA-678): use conversation history in self-improve runs (#20)

* fix(slack:PLA-678): improve progress update readability (#21)

* fix(ci:PLA-678): restore main release pipeline health (#22)

* fix(ci:PLA-678): restore main release pipeline health

* fix(ci:PLA-678): harden auto-response token fallback

* fix(ci:PLA-678): pin setup-bun to published release

* test(ci:PLA-678): align slack thread session expectations

* fix(sre:PLA-678): harden Slack reply delivery and image release flow (#23)

* fix(slack:PLA-678): harden thread-scoped reply delivery

* fix(slack:PLA-678): satisfy lint after rebase

* ci(release:PLA-678): move image release to cached ecr flow

* ci(release:PLA-678): use official docker build actions

* fix(slack:PLA-722): preserve progress updates during final-answer gating (#24)

* fix(sre:PLA-724): restore ECR runtime image toolchain (#25)

* fix(failover): classify HTTP 402 as rate_limit when payload indicates usage limit (#30484) (#36802)

* fix(failover): classify HTTP 402 as rate_limit when payload indicates usage limit (#30484)

Some providers (notably Anthropic Claude Max plan) surface temporary
usage/rate-limit failures as HTTP 402 instead of 429. Before this change,
all 402s were unconditionally mapped to 'billing', which produced a
misleading 'run out of credits' warning for Max plan users who simply
hit their usage window.

This follows the same pattern introduced for HTTP 400 in #36783: check
the error message for an explicit rate-limit signal before falling back
to the default status-code classification.

- classifyFailoverReasonFromHttpStatus now returns 'rate_limit' for 402
  when isRateLimitErrorMessage matches the payload text
- Added regression tests covering both the rate-limit and billing paths
  on 402

* fix: narrow 402 rate-limit matcher to prevent billing misclassification

The original implementation used isRateLimitErrorMessage(), which matches
phrases like 'quota exceeded' that legitimately appear in billing errors.

This commit replaces it with a narrow, 402-specific matcher that requires
BOTH retry language (try again/retry/temporary/cooldown) AND limit
terminology (usage limit/rate limit/organization usage).

Prevents misclassification of errors like:
'HTTP 402: exceeded quota, please add credits' -> billing (not rate_limit)

Added regression test for the ambiguous case.

---------

Co-authored-by: Val Alexander <[email protected]>

* fix(mattermost): allow reachable interaction callback URLs (#37543)

Merged via squash.

Prepared head SHA: 4d593731be5a5dcbf3106d596b38acfeb8cf0aa8
Co-authored-by: mukhtharcm <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* fix(auth): prefer Anthropic API key over stale OAuth profiles

* fix(runtime): raise default agent timeout to one hour

* feat(runtime): support direct env fallback for agent timeout

---------

Signed-off-by: joshavant <[email protected]>
Co-authored-by: Gustavo Madeira Santana <[email protected]>
Co-authored-by: Mariano <[email protected]>
Co-authored-by: leepokai <[email protected]>
Co-authored-by: Bob <[email protected]>
Co-authored-by: Onur <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: huangcj <[email protected]>
Co-authored-by: gumadeiras <[email protected]>
Co-authored-by: Sid <[email protected]>
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: shakkernerd <[email protected]>
Co-authored-by: a <[email protected]>
Co-authored-by: echoVic <[email protected]>
Co-authored-by: Shakker <[email protected]>
Co-authored-by: liuxiaopai-ai <[email protected]>
Co-authored-by: Rodrigo Uroz <[email protected]>
Co-authored-by: rodrigouroz <[email protected]>
Co-authored-by: jalehman <[email protected]>
Co-authored-by: Kai <[email protected]>
Co-authored-by: RealKai42 <[email protected]>
Co-authored-by: 青雲 <[email protected]>
Co-authored-by: echoVic <[email protected]>
Co-authored-by: Darshil <[email protected]>
Co-authored-by: Ho Lim <[email protected]>
Co-authored-by: dvrshil <[email protected]>
Co-authored-by: Isis Anisoptera <[email protected]>
Co-authored-by: Madoka <[email protected]>
Co-authored-by: Xu Zimo <[email protected]>
Co-authored-by: Munem Hashmi <[email protected]>
Co-authored-by: bmendonca3 <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: Nhj <[email protected]>
Co-authored-by: 倪汉杰0668001185 <[email protected]>
Co-authored-by: zhengquanliu <[email protected]>
Co-authored-by: nick <[email protected]>
Co-authored-by: linhey <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: rexl2018 <[email protected]>
Co-authored-by: sline <[email protected]>
Co-authored-by: 0xsline <[email protected]>
Co-authored-by: Harold Hunt <[email protected]>
Co-authored-by: Shivam <[email protected]>
Co-authored-by: 不做了睡大觉 <[email protected]>
Co-authored-by: alexyyyander <[email protected]>
Co-authored-by: alexyyyander <[email protected]>
Co-authored-by: Octane0411 <[email protected]>
Co-authored-by: Linux2010 <[email protected]>
Co-authored-by: echoVic <[email protected]>
Co-authored-by: Joseph Turian <[email protected]>
Co-authored-by: turian <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Tony Dehnke <[email protected]>
Co-authored-by: Sid-Qin <[email protected]>
Co-authored-by: kevinWangSheng <[email protected]>
Co-authored-by: ningding97 <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: clawbie <[email protected]>
Co-authored-by: Takhoffman <[email protected]>
Co-authored-by: Ayane <[email protected]>
Co-authored-by: Ayane <[email protected]>
Co-authored-by: StingNing <[email protected]>
Co-authored-by: maweibin <[email protected]>
Co-authored-by: maweibin <[email protected]>
Co-authored-by: Josh Avant <[email protected]>
Co-authored-by: Bin Deng <[email protected]>
Co-authored-by: Byungsker <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Co-authored-by: Altay <[email protected]>
Co-authored-by: jiangnan <[email protected]>
Co-authored-by: jnMetaCode <[email protected]>
Co-authored-by: Jacob Riff <[email protected]>
Co-authored-by: jriff <[email protected]>
Co-authored-by: Naylenv <[email protected]>
Co-authored-by: Bill <[email protected]>
Co-authored-by: 2233admin <[email protected]>
Co-authored-by: 2233admin <[email protected]>
Co-authored-by: littleben <[email protected]>
Co-authored-by: littleben <[email protected]>
Co-authored-by: OpenClaw Agent <[email protected]>
Co-authored-by: Vignesh Natarajan <[email protected]>
Co-authored-by: zerone0x <[email protected]>
Co-authored-by: zerone0x <[email protected]>
Co-authored-by: dunamismax <[email protected]>
Co-authored-by: Octane <[email protected]>
Co-authored-by: Mitsuyuki Osabe <[email protected]>
Co-authored-by: Tak <[email protected]>
Co-authored-by: Tyler Yust <[email protected]>
Co-authored-by: Hinata Kaga (samon) <[email protected]>
Co-authored-by: dorukardahan <[email protected]>
Co-authored-by: Tyler Yust <[email protected]>
Co-authored-by: Brenner Spear <[email protected]>
Co-authored-by: aerelune <[email protected]>
Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: zhouhe-xydt <[email protected]>
Co-authored-by: Vignesh <[email protected]>
Co-authored-by: OpenClaw SRE Bot <[email protected]>
Co-authored-by: Xinhua Gu <[email protected]>
Co-authored-by: Val Alexander <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: feishu Channel integration: feishu size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feishu: mp4 video messages sent as text link (msg_type should be "media" not "file")

2 participants