Skip to content

fix(ui): stop dashboard chat history reload storm#45541

Merged
BunsDev merged 9 commits intomainfrom
ui/dashboard-v2.1.3
Mar 14, 2026
Merged

fix(ui): stop dashboard chat history reload storm#45541
BunsDev merged 9 commits intomainfrom
ui/dashboard-v2.1.3

Conversation

@BunsDev
Copy link
Copy Markdown
Member

@BunsDev BunsDev commented Mar 13, 2026

Summary

  • Problem: dashboard v2 was reloading chat.history on every live tool-result event during chat runs.
  • Why it matters: tool-heavy runs could trigger repeated full-history refreshes, causing rerender storms and a frozen-feeling chat UI.
  • What changed: removed the per-tool-result history reload and kept the existing final-event history refresh; added a regression test covering both behaviors.
  • What did NOT change (scope boundary): auth, storage, rendering sanitization, and tool-stream message shaping.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #

User-visible / Behavior Changes

  • Dashboard chat stays responsive during tool-heavy runs because live tool results no longer trigger repeated full-history reloads.

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (Yes)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:
    • This reduces network activity by removing redundant chat.history calls during live tool-result events. The final-event refresh remains in place so persisted history still replaces streamed state at the end of the run.

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local Node/pnpm dev env
  • Model/provider: mocked gateway for UI repro
  • Integration/channel (if any): Control UI / dashboard v2 chat
  • Relevant config (redacted): default local dev config

Steps

  1. Open dashboard v2 chat in dev.
  2. Simulate a tool-heavy run that emits live agent tool-result events.
  3. Observe whether chat history reloads on each tool result or only after the terminal final event.

Expected

  • No full-history reload storm during live tool-result events.
  • One persisted-history refresh after the final chat event.

Actual

  • With this change, tool-result events no longer trigger chat.history reloads; the final chat event still triggers the single refresh.

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
    • Reproduced the event pattern in the dev dashboard with a mocked gateway.
    • Confirmed chat.history count stayed flat across a tool-result event and increased once on the final event.
  • Edge cases checked:
    • Final-event refresh still happens after tool output is used.
  • What you did not verify:
    • Real provider/channel traffic beyond the mocked dashboard event flow.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly:
    • Revert this PR to restore the old per-tool-result reload behavior.
  • Files/config to restore:
    • ui/src/ui/app-gateway.ts
  • Known bad symptoms reviewers should watch for:
    • Missing persisted tool output after the final event.

Risks and Mitigations

  • Risk:
    • A terminal refresh path might be missed for a tool-using run.
    • Mitigation:
      • Regression coverage now asserts no reload on live tool results and exactly one reload after the final event when tool output was used.

Verification Notes

  • pnpm build
  • pnpm check
  • pnpm -C ui exec vitest run --config vitest.node.config.ts src/ui/app-gateway.node.test.ts
  • OPENCLAW_TEST_PROFILE=low OPENCLAW_TEST_SERIAL_GATEWAY=1 pnpm test ❌ unrelated existing failure in src/security/temp-path-guard.test.ts (src/plugins/test-helpers/fs-fixtures.ts flagged by the guard); not caused by this diff.

@openclaw-barnacle openclaw-barnacle bot added app: web-ui App: web-ui size: S maintainer Maintainer-authored PR labels Mar 13, 2026
@BunsDev BunsDev self-assigned this Mar 13, 2026
@BunsDev BunsDev marked this pull request as ready for review March 13, 2026 23:58
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 14, 2026

Greptile Summary

This PR removes a redundant per-tool-result call to loadChatHistory inside handleGatewayEventUnsafe, replacing it with the already-existing single reload that fires in handleTerminalChatEvent when hadToolEvents && state === "final". The fix correctly eliminates the reload storm during tool-heavy runs while keeping the final-event refresh path intact.

  • Happy path verified: loadChatHistory is still called exactly once at the end of a successful tool-using run, via handleTerminalChatEvent.
  • Regression tests added: two new tests cover the "no reload on live tool result" and "one reload on final chat event with tool output" paths; the mock and host fixture are set up correctly.
  • Error/abort regression: handleTerminalChatEvent only gates loadChatHistory behind state === "final". For error and aborted runs, resetToolStream clears the live streaming tool state but no history reload is triggered. Before this PR the per-tool-result reloads would have already fetched any server-persisted tool outputs; after this PR those outputs will not be loaded in errored or aborted runs, leaving the chat history empty of tool activity.

Confidence Score: 3/5

  • Safe to merge for the happy path; error/abort runs with tool results silently lose their persisted history refresh.
  • The core fix is correct and well-tested for the final-state path. However, removing the per-tool-result loadChatHistory also removes the only mechanism that loaded persisted history after error/aborted runs that used tools. handleTerminalChatEvent only calls loadChatHistory for state === "final", so resetToolStream clears the live stream state on abort/error without replacing it with server-persisted data. This is a real behavioral regression for a non-trivial failure scenario, which is why the score is 3 rather than 4–5.
  • ui/src/ui/app-gateway.ts — specifically the handleTerminalChatEvent function around lines 304–308 where the history reload is gated exclusively on state === "final".

Comments Outside Diff (1)

  1. ui/src/ui/app-gateway.ts, line 304-308 (link)

    History not reloaded after error/abort with tool results

    loadChatHistory is only called when hadToolEvents && state === "final". For runs that end with state === "error" or state === "aborted", resetToolStream clears the live streaming tool state (including chatToolMessages) but no history reload fires. Before this PR, each per-tool-result call to loadChatHistory would have already loaded any server-persisted tool outputs into chatMessages; after the abort/error the tool cards would disappear from the stream view, but the persisted history would still show them.

    With this change, if a run aborts or errors after producing tool results, neither path reloads history — the stream state is cleared and the persisted outputs are never fetched. The chat UI will appear as though no tool work happened.

    Consider also reloading when tools were used and the run terminated abnormally:

      if (hadToolEvents && state === "final") {
        void loadChatHistory(host as unknown as OpenClawApp);
        return true;
      }
      if (hadToolEvents && (state === "error" || state === "aborted")) {
        void loadChatHistory(host as unknown as OpenClawApp);
      }
      return false;
    
Prompt To Fix All With AI
This is a comment left during a code review.
Path: ui/src/ui/app-gateway.ts
Line: 304-308

Comment:
**History not reloaded after error/abort with tool results**

`loadChatHistory` is only called when `hadToolEvents && state === "final"`. For runs that end with `state === "error"` or `state === "aborted"`, `resetToolStream` clears the live streaming tool state (including `chatToolMessages`) but no history reload fires. Before this PR, each per-tool-result call to `loadChatHistory` would have already loaded any server-persisted tool outputs into `chatMessages`; after the abort/error the tool cards would disappear from the stream view, but the persisted history would still show them.

With this change, if a run aborts or errors after producing tool results, neither path reloads history — the stream state is cleared and the persisted outputs are never fetched. The chat UI will appear as though no tool work happened.

Consider also reloading when tools were used and the run terminated abnormally:

```
  if (hadToolEvents && state === "final") {
    void loadChatHistory(host as unknown as OpenClawApp);
    return true;
  }
  if (hadToolEvents && (state === "error" || state === "aborted")) {
    void loadChatHistory(host as unknown as OpenClawApp);
  }
  return false;
```

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 917b26d

@openclaw-barnacle openclaw-barnacle bot added channel: discord Channel integration: discord channel: matrix Channel integration: matrix channel: telegram Channel integration: telegram channel: tlon Channel integration: tlon channel: voice-call Channel integration: voice-call size: M and removed size: S labels Mar 14, 2026
@BunsDev BunsDev merged commit 0e8672a into main Mar 14, 2026
6 checks passed
@BunsDev BunsDev deleted the ui/dashboard-v2.1.3 branch March 14, 2026 00:19
frankekn pushed a commit to xinhuagu/openclaw that referenced this pull request Mar 14, 2026
* UI: stop dashboard chat history reload storm

* Changelog: add PR number for chat reload fix

* fix: resolve branch typecheck regressions
ecochran76 pushed a commit to ecochran76/openclaw that referenced this pull request Mar 14, 2026
* UI: stop dashboard chat history reload storm

* Changelog: add PR number for chat reload fix

* fix: resolve branch typecheck regressions
jbencook added a commit to harborworks/openclaw that referenced this pull request Mar 16, 2026
* refactor: share discord binding update loop

* test: dedupe discord route fixture setup

* refactor: share discord trailing media delivery

* test: dedupe model info reply setup

* test: dedupe inline action skip assertions

* test: dedupe discord forwarded media assertions

* test: dedupe discord retry delivery setup

* test: dedupe discord gateway proxy register flow

* test: dedupe discord provider account config harness

* refactor: share discord channel override config type

* refactor: share session entry persistence update

* refactor: share discord preflight shared fields

* test: dedupe discord listener deferred setup

* test: dedupe session idle timeout assertions

* test: dedupe discord bound slash dispatch setup

* test: dedupe discord queue preflight setup

* test: dedupe discord preflight helpers

* refactor: share discord exec approval helpers

* refactor: share auto reply helper fixtures

* refactor: share embedded run and discord test helpers

* refactor: share self hosted provider auth flow

* test: share zalouser test helpers

* refactor: share bluebubbles multipart helpers

* test: share synology channel harness

* test: share feishu monitor startup mocks

* test: share matrix sdk test mocks

* test: reuse feishu streaming merge helper

* test: simplify mattermost token summary fixtures

* test: share pairing setup resolution assertions

* test: preserve wrapper behavior for targeted runs FIX OOM issues(openclaw#45518)

* test: preserve wrapper behavior for targeted runs

* test: tighten targeted wrapper routing

* fix: tighten path guard coverage

* fix(imessage): sanitize SCP remote path to prevent shell metacharacter injection

References GHSA-g2f6-pwvx-r275.

* fix: tighten runtime status coverage

* fix: tighten package json coverage

* fix: tighten bonjour error coverage

* fix: tighten package tag coverage

* fix: tighten machine name coverage

* test: tighten gateway process argv coverage

* test: tighten install safe path coverage

* test: tighten tmp dir fallback coverage

* test: tighten brew helper coverage

* test: add archive staging helper coverage

* fix: tighten device identity helper coverage

* UI: fix chat context notice icon sizing (openclaw#45533)

* UI: fix chat context notice icon sizing

* Update ui/src/ui/views/chat.browser.test.ts

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

* UI: tighten chat context notice regression test

---------

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

* test: tighten transport ready coverage

* test: tighten channel summary coverage

* test: tighten safe bin policy coverage

* fix: tighten safe bin runtime policy coverage

* fix: tighten duration formatter coverage

* fix: harden browser existing-session flows

* test: tighten fetch helper coverage

* test: extract provider usage load coverage

* test: extract fingerprint helper coverage

* test: add gateway tls helper coverage

* test: extract archive helper coverage

* test: extract apns relay coverage

* test: extract apns auth helper coverage

* test: extract apns store coverage

* test: add device bootstrap coverage

* test: add state migration coverage

* test: tighten apns send coverage

* fix(ui): stop dashboard chat history reload storm (openclaw#45541)

* UI: stop dashboard chat history reload storm

* Changelog: add PR number for chat reload fix

* fix: resolve branch typecheck regressions

* test: tighten fetch and channel summary coverage

* fix: retry Telegram inbound media downloads over IPv4 fallback (openclaw#45327)

* fix: retry telegram inbound media downloads over ipv4

* fix: preserve telegram media retry errors

* fix: redact telegram media fetch errors

* fix: harden bootstrap and transport ready coverage

* test: expand browser existing-session coverage

* fix: tighten package tag and channel summary coverage

* fix: tighten runtime status detail coverage

* fix: support bun lockfile detection

* test: add home relative path coverage

* test: tighten json file lock coverage

* test: tighten path prepend casing coverage

* refactor: share models command helpers

* test: share cli help version assertions

* test: share venice model response fixtures

* test: share browser loopback auth error assertions

* test: share config pruning defaults setup

* test: share cron telegram delivery failure assertions

* test: share agent acp turn helpers

* test: share systemd service test helpers

* test: share scheduled task stop helpers

* test: share lane delivery final helpers

* test: share outbound media fallback helpers

* test: share telegram sticky fetch helpers

* test: share embedded compaction hook helpers

* test: share sanitize session usage helpers

* test: share telegram draft stream helpers

* test: share telegram account helpers

* test: share line webhook gating helpers

* test: share heartbeat scheduler helpers

* test: share config-only channel status helpers

* test: share restart health helpers

* test: share lifecycle config guard helpers

* test: share daemon cli service helpers

* test: share qr cli setup code helpers

* test: share gateway chat run helpers

* refactor: share daemon lifecycle restart helpers

* refactor: share daemon launchd and path helpers

* test: share schtasks gateway script fixture

* test: share startup auth token fixtures

* test: share gateway reload helpers

* test: share plugin http auth helpers

* test: share gateway hook and cron helpers

* test: share gateway chat history setup

* refactor: share gateway chat text normalization

* refactor: share gateway connection auth options

* test: share channel health helpers

* refactor: share plugin directory helpers

* refactor: share browser route helpers

* refactor: share cli install helpers

* test: tighten system run command coverage

* test: add parallels windows smoke harness

* fix: force-stop lingering gateway client sockets

* test: share gateway route auth helpers

* test: share browser route test helpers

* test: share gateway status auth fixtures

* test: share models list forward compat fixtures

* fix: tighten bonjour whitespace error coverage

* docs: reorder changelog highlights by user impact

* test: tighten proxy fetch helper coverage

* test: tighten path guard helper coverage

* test: tighten warning filter coverage

* test: tighten wsl detection coverage

* test: tighten system run command normalization coverage

* fix(feishu): preserve non-ASCII filenames in file uploads (openclaw#33912) (openclaw#34262)

* fix(feishu): preserve non-ASCII filenames in file uploads (openclaw#33912)

* style(feishu): format media test file

* fix(feishu): preserve UTF-8 filenames in file uploads (openclaw#34262) thanks @fabiaodemianyang

---------

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

* test: tighten is-main helper coverage

* test: tighten json file helper coverage

* fix: resolve current ci regressions

* test: tighten backoff abort coverage

* docs(changelog): note upcoming security fixes

* test: tighten bonjour ciao coverage

* test: tighten channel activity account isolation

* test: tighten update channel display precedence

* test: tighten node list parse fallback coverage

* test: tighten package tag prefix matching

* test: tighten outbound identity normalization

* test: tighten outbound session context coverage

* macOS: respect exec-approvals.json settings in gateway prompter (openclaw#13707)

Fix macOS gateway exec approvals to respect exec-approvals.json.

This updates the macOS gateway prompter to resolve per-agent exec approval policy before deciding whether to show UI, use agentId for policy lookup, honor askFallback when prompts cannot be presented, and resolve no-prompt decisions from the configured security policy instead of hardcoded allow-once behavior. It also adds regression coverage for ask-policy and allowlist-fallback behavior, plus a changelog entry for the fix.

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

* fix: tighten target error hint coverage

* test: tighten prototype key matching

* test: tighten hostname normalization coverage

* fix(ui): keep oversized chat replies readable (openclaw#45559)

* fix(ui): keep oversized chat replies readable

* Update ui/src/ui/markdown.ts

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

* fix(ui): preserve oversized markdown whitespace

---------

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

* test: tighten openclaw exec env coverage

* fix: tighten pairing token blank handling

* test: tighten target error hint trimming

* test: tighten node shell platform normalization

* fix(gateway/ui): restore control-ui auth bypass and classify connect failures (openclaw#45512)

Merged via squash.

Prepared head SHA: 42b5595
Co-authored-by: sallyom <[email protected]>
Co-authored-by: BunsDev <[email protected]>
Reviewed-by: @BunsDev

* fix(macos): prevent PortGuard from killing Docker Desktop in remote mode (openclaw#13798)

fix(macos): prevent PortGuardian from killing Docker Desktop in remote mode (openclaw#6755)

PortGuardian.sweep() was killing non-SSH processes holding the gateway
port in remote mode. When the gateway runs in a Docker container,
`com.docker.backend` owns the port-forward, so this could shut down
Docker Desktop entirely.

Changes:
- accept any process on the gateway port in remote mode
- add a defense-in-depth guard to skip kills in remote mode
- update remote-mode port diagnostics/reporting to match
- add regression coverage for Docker and local-mode behavior
- add a changelog entry for the fix

Co-Authored-By: ImLukeF <[email protected]>

* test: fix current ci regressions

* test: share outbound action runner helpers

* test: share telegram monitor startup helpers

* refactor: share self hosted provider plugin helpers

* test: share outbound delivery helpers

* refactor: share onboarding diagnostics type

* refactor: share delimited channel entry parsing

* refactor: share zalo send context validation

* refactor: share terminal note wrapping

* refactor: share tts request setup

* refactor: share gateway timeout parsing

* refactor: share session send context lines

* refactor: share memory tool builders

* refactor: share browser console result formatting

* refactor: share pinned sandbox entry finalization

* refactor: share tool result char estimation

* refactor: share agent tool fixture helpers

* test: share compaction retry timer helpers

* test: share embedded workspace attempt helpers

* refactor: share whatsapp outbound adapter base

* refactor: share zalo status issue helpers

* test: share whatsapp outbound poll fixtures

* refactor: share telegram reply chunk threading

* refactor: share daemon install cli setup

* fix: widen telegram reply progress typing

* refactor: share slack text truncation

* refactor: share allowlist wildcard matching

* refactor: declone model picker model ref parsing

* refactor: share dual text command gating

* test: share startup account lifecycle helpers

* test: share status issue assertion helpers

* fix: restore imessage control command flag

* test: share web fetch header helpers

* refactor: share session tool context setup

* test: share memory tool helpers

* refactor: share request url resolution

* Changelog: credit embedded runner queue deadlock fix

* fix(voicewake): avoid crash on foreign transcript ranges

* refactor(voicewake): mark transcript parameter unused

* docs(changelog): note voice wake crash fix

* fix: harden gateway status rpc smoke

* test: add parallels linux smoke harness

* fix(sessions): create transcript file on chat.inject when missing (openclaw#36645)

`chat.inject` called `appendAssistantTranscriptMessage` with
`createIfMissing: false`, causing a hard error when the transcript
file did not exist on disk despite having a valid `transcriptPath`
in session metadata. This commonly happens with ACP oneshot/run
sessions where the session entry is created but the transcript file
is not yet materialized.

The fix is a one-character change: `createIfMissing: true`. The
`ensureTranscriptFile` helper already handles directory creation
and file initialization safely.

Fixes openclaw#36170

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

* fix: harden discord guild allowlist resolution

* chore: update dependencies

* Plugins: fail fast on channel and binding collisions (openclaw#45628)

* Plugins: reject duplicate channel ids

* Bindings: reject duplicate adapter registration

* Plugins: fail on export id mismatch

* feat: add node-connect skill

* test: share directory runtime helpers

* refactor: share open allowFrom config checks

* test: share send cfg threading helpers

* refactor: reduce extension channel setup duplication

* refactor: share extension channel status summaries

* test: share feishu startup mock modules

* test: share plugin api test harness

* refactor: share extension monitor runtime setup

* refactor: share extension deferred and runtime helpers

* test: share sandbox fs bridge seeded workspace

* test: share subagent gateway mock setup

* test: share models config merge helpers

* test: share workspace skills snapshot helpers

* test: share context lookup helpers

* test: share timeout failover assertions

* test: share model selection config helpers

* test: share provider discovery auth fixtures

* test: share subagent announce timeout helpers

* test: share workspace skill test helpers

* refactor: share exec host approval helpers

* test: share oauth profile fixtures

* test: share memory search config helpers

* fix(macos): align minimum Node.js version with runtime guard (22.16.0) (openclaw#45640)

* macOS: align minimum Node.js version with runtime guard

* macOS: add boundary and failure-message coverage for RuntimeLocator

* docs: add changelog note for the macOS runtime locator fix

* credit: original fix direction from @sumleo, cleaned up and rebased in openclaw#45640 by @ImLukeF

* fix(agents): preserve blank local custom-provider API keys after onboarding

Co-authored-by: Xinhua Gu <[email protected]>

* fix(browser): harden existing-session driver validation and session lifecycle (openclaw#45682)

* fix(browser): harden existing-session driver validation, session lifecycle, and code quality

Fix config validation rejecting existing-session profiles that lack
cdpPort/cdpUrl (they use Chrome MCP auto-connect instead). Fix callTool
tearing down the MCP session on tool-level errors (element not found,
script error), which caused expensive npx re-spawns. Skip unnecessary
CDP port allocation for existing-session profiles. Remove redundant
ensureChromeMcpAvailable call in isReachable.

Extract shared ARIA role sets (INTERACTIVE_ROLES, CONTENT_ROLES,
STRUCTURAL_ROLES) into snapshot-roles.ts so both the Playwright and
Chrome MCP snapshot paths stay in sync. Add usesChromeMcp capability
flag and replace ~20 scattered driver === "existing-session" string
checks with the centralized flag.

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

* fix(browser): harden existing-session driver validation and session lifecycle (openclaw#45682) (thanks @odysseus0)

---------

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

* fix(ci): repair helper typing regressions

* fix: default Android TLS setup codes to port 443

* fix: unblock discord startup on deploy rate limits

* fix(feishu): add early event-level dedup to prevent duplicate replies (openclaw#43762)

* fix(feishu): add early event-level dedup to prevent duplicate replies

Add synchronous in-memory dedup at EventDispatcher handler level using
message_id as key with 5-minute TTL and 2000-entry cap.

This catches duplicate events immediately when they arrive from the Lark
SDK — before the inbound debouncer or processing queue — preventing the
race condition where two concurrent dispatches enter the pipeline before
either records the messageId in the downstream dedup layer.

Fixes the root cause reported in openclaw#42687.

* fix(feishu): correct inverted dedup condition

check() returns false on first call (new key) and true on subsequent
calls (duplicate). The previous `!check()` guard was inverted —
dropping every first delivery and passing all duplicates.

Remove the negation so the guard correctly drops duplicates.

* fix(feishu): simplify eventDedup key — drop redundant accountId prefix

eventDedup is already scoped per account (one instance per
registerEventHandlers call), so the accountId prefix in the cache key
is redundant. Use `evt:${messageId}` instead.

* fix(feishu): share inbound processing claim dedupe

---------

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

* fix(models): apply Gemini model-id normalization to google-vertex provider (openclaw#42435)

* fix(models): apply Gemini model-id normalization to google-vertex provider

The existing normalizeGoogleModelId() (which maps e.g. gemini-3.1-flash-lite
to gemini-3.1-flash-lite-preview) was only applied when the provider was
"google". Users configuring google-vertex/gemini-3.1-flash-lite would get
a "missing" model because the -preview suffix was never appended.

Extend the normalization to google-vertex in both model-selection
(parseModelRef path) and normalizeProviders (config normalization path).

Ref: openclaw#36838
Ref: openclaw#36918 (comment)


* fix(models): normalize google-vertex flash-lite

* fix(models): place unreleased changelog entry last

* fix(models): place unreleased changelog entry before releases

* fix(browser): add browser session selection

* build(android): add auto-bump signed aab release script

* build(android): strip unused dnsjava resolver service before R8

* test(discord): align rate limit error mock with carbon

* docs: fix changelog formatting

* fix: keep exec summaries inline

* build: shrink Android app release bundle

* Gateway: treat scope-limited probe RPC as degraded reachability (openclaw#45622)

* Gateway: treat scope-limited probe RPC as degraded

* Docs: clarify gateway probe degraded scope output

* test: fix CI type regressions in gateway and outbound suites

* Tests: fix Node24 diffs theme loading and Windows assertions

* Tests: fix extension typing after main rebase

* Tests: fix Windows CI regressions after rebase

* Tests: normalize executable path assertions on Windows

* Tests: remove duplicate gateway daemon result alias

* Tests: stabilize Windows approval path assertions

* Tests: fix Discord rate-limit startup fixture typing

* Tests: use Windows-friendly relative exec fixtures

---------

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

* build: upload Android native debug symbols

* fix(browser): prefer user profile over chrome relay

* chore: bump pi to 0.58.0

* test: harden parallels all-os smoke harness

* fix: keep windows onboarding logs ascii-safe

* docs: reorder unreleased changelog by impact

* build: prepare 2026.3.13-beta.1

* ci: add npm token fallback for npm releases

* fix(gateway): bound unanswered client requests (openclaw#45689)

* fix(gateway): bound unanswered client requests

* fix(gateway): skip default timeout for expectFinal requests

* fix(gateway): preserve gateway call timeouts

* fix(gateway): localize request timeout policy

* fix(gateway): clamp explicit request timeouts

* fix(gateway): clamp default request timeout

* Revert "Browser: scope nested batch failures in switch"

This reverts commit aaeb348.

* build: prepare 2026.3.13 release

* fix: keep android canvas home visible after restart

* chore: update appcast for 2026.3.13 release

* fix(browser): restore batch playwright dispatch

* fix(harbor): preserve shared-auth scopes and harbor runtime behavior

---------

Co-authored-by: Peter Steinberger <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: Robin Waslander <[email protected]>
Co-authored-by: Val Alexander <[email protected]>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: fabiaodemianyang <[email protected]>
Co-authored-by: Steven <[email protected]>
Co-authored-by: ImLukeF <[email protected]>
Co-authored-by: Sally O'Malley <[email protected]>
Co-authored-by: sallyom <[email protected]>
Co-authored-by: Jaehoon You <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: 2233admin <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
Co-authored-by: Xinhua Gu <[email protected]>
Co-authored-by: George Zhang <[email protected]>
Co-authored-by: yunweibang <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: Muhammed Mukhthar CM <[email protected]>
Co-authored-by: Josh Avant <[email protected]>
Co-authored-by: Mainframe <[email protected]>
Interstellar-code pushed a commit to Interstellar-code/operator1 that referenced this pull request Mar 16, 2026
* UI: stop dashboard chat history reload storm

* Changelog: add PR number for chat reload fix

* fix: resolve branch typecheck regressions
juliopx added a commit to juliopx/mindbot that referenced this pull request Mar 16, 2026
* fix(imessage): sanitize SCP remote path to prevent shell metacharacter injection

References GHSA-g2f6-pwvx-r275.

* fix: tighten runtime status coverage

* fix: tighten package json coverage

* fix: tighten bonjour error coverage

* fix: tighten package tag coverage

* fix: tighten machine name coverage

* test: tighten gateway process argv coverage

* test: tighten install safe path coverage

* test: tighten tmp dir fallback coverage

* test: tighten brew helper coverage

* test: add archive staging helper coverage

* fix: tighten device identity helper coverage

* UI: fix chat context notice icon sizing (openclaw#45533)

* UI: fix chat context notice icon sizing

* Update ui/src/ui/views/chat.browser.test.ts

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

* UI: tighten chat context notice regression test

---------

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

* test: tighten transport ready coverage

* test: tighten channel summary coverage

* test: tighten safe bin policy coverage

* fix: tighten safe bin runtime policy coverage

* fix: tighten duration formatter coverage

* fix: harden browser existing-session flows

* test: tighten fetch helper coverage

* test: extract provider usage load coverage

* test: extract fingerprint helper coverage

* test: add gateway tls helper coverage

* test: extract archive helper coverage

* test: extract apns relay coverage

* test: extract apns auth helper coverage

* test: extract apns store coverage

* test: add device bootstrap coverage

* test: add state migration coverage

* test: tighten apns send coverage

* fix(ui): stop dashboard chat history reload storm (openclaw#45541)

* UI: stop dashboard chat history reload storm

* Changelog: add PR number for chat reload fix

* fix: resolve branch typecheck regressions

* test: tighten fetch and channel summary coverage

* fix: retry Telegram inbound media downloads over IPv4 fallback (openclaw#45327)

* fix: retry telegram inbound media downloads over ipv4

* fix: preserve telegram media retry errors

* fix: redact telegram media fetch errors

* fix: harden bootstrap and transport ready coverage

* test: expand browser existing-session coverage

* fix: tighten package tag and channel summary coverage

* fix: tighten runtime status detail coverage

* fix: support bun lockfile detection

* test: add home relative path coverage

* test: tighten json file lock coverage

* test: tighten path prepend casing coverage

* refactor: share models command helpers

* test: share cli help version assertions

* test: share venice model response fixtures

* test: share browser loopback auth error assertions

* test: share config pruning defaults setup

* test: share cron telegram delivery failure assertions

* test: share agent acp turn helpers

* test: share systemd service test helpers

* test: share scheduled task stop helpers

* test: share lane delivery final helpers

* test: share outbound media fallback helpers

* test: share telegram sticky fetch helpers

* test: share embedded compaction hook helpers

* test: share sanitize session usage helpers

* test: share telegram draft stream helpers

* test: share telegram account helpers

* test: share line webhook gating helpers

* test: share heartbeat scheduler helpers

* test: share config-only channel status helpers

* test: share restart health helpers

* test: share lifecycle config guard helpers

* test: share daemon cli service helpers

* test: share qr cli setup code helpers

* test: share gateway chat run helpers

* refactor: share daemon lifecycle restart helpers

* refactor: share daemon launchd and path helpers

* test: share schtasks gateway script fixture

* test: share startup auth token fixtures

* test: share gateway reload helpers

* test: share plugin http auth helpers

* test: share gateway hook and cron helpers

* test: share gateway chat history setup

* refactor: share gateway chat text normalization

* refactor: share gateway connection auth options

* test: share channel health helpers

* refactor: share plugin directory helpers

* refactor: share browser route helpers

* refactor: share cli install helpers

* test: tighten system run command coverage

* test: add parallels windows smoke harness

* fix: force-stop lingering gateway client sockets

* test: share gateway route auth helpers

* test: share browser route test helpers

* test: share gateway status auth fixtures

* test: share models list forward compat fixtures

* fix: tighten bonjour whitespace error coverage

* docs: reorder changelog highlights by user impact

* test: tighten proxy fetch helper coverage

* test: tighten path guard helper coverage

* test: tighten warning filter coverage

* test: tighten wsl detection coverage

* test: tighten system run command normalization coverage

* fix(feishu): preserve non-ASCII filenames in file uploads (openclaw#33912) (openclaw#34262)

* fix(feishu): preserve non-ASCII filenames in file uploads (openclaw#33912)

* style(feishu): format media test file

* fix(feishu): preserve UTF-8 filenames in file uploads (openclaw#34262) thanks @fabiaodemianyang

---------

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

* test: tighten is-main helper coverage

* test: tighten json file helper coverage

* fix: resolve current ci regressions

* test: tighten backoff abort coverage

* docs(changelog): note upcoming security fixes

* test: tighten bonjour ciao coverage

* test: tighten channel activity account isolation

* test: tighten update channel display precedence

* test: tighten node list parse fallback coverage

* test: tighten package tag prefix matching

* test: tighten outbound identity normalization

* test: tighten outbound session context coverage

* macOS: respect exec-approvals.json settings in gateway prompter (openclaw#13707)

Fix macOS gateway exec approvals to respect exec-approvals.json.

This updates the macOS gateway prompter to resolve per-agent exec approval policy before deciding whether to show UI, use agentId for policy lookup, honor askFallback when prompts cannot be presented, and resolve no-prompt decisions from the configured security policy instead of hardcoded allow-once behavior. It also adds regression coverage for ask-policy and allowlist-fallback behavior, plus a changelog entry for the fix.

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

* fix: tighten target error hint coverage

* test: tighten prototype key matching

* test: tighten hostname normalization coverage

* fix(ui): keep oversized chat replies readable (openclaw#45559)

* fix(ui): keep oversized chat replies readable

* Update ui/src/ui/markdown.ts

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

* fix(ui): preserve oversized markdown whitespace

---------

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

* test: tighten openclaw exec env coverage

* fix: tighten pairing token blank handling

* test: tighten target error hint trimming

* test: tighten node shell platform normalization

* fix(gateway/ui): restore control-ui auth bypass and classify connect failures (openclaw#45512)

Merged via squash.

Prepared head SHA: 42b5595
Co-authored-by: sallyom <[email protected]>
Co-authored-by: BunsDev <[email protected]>
Reviewed-by: @BunsDev

* fix(macos): prevent PortGuard from killing Docker Desktop in remote mode (openclaw#13798)

fix(macos): prevent PortGuardian from killing Docker Desktop in remote mode (openclaw#6755)

PortGuardian.sweep() was killing non-SSH processes holding the gateway
port in remote mode. When the gateway runs in a Docker container,
`com.docker.backend` owns the port-forward, so this could shut down
Docker Desktop entirely.

Changes:
- accept any process on the gateway port in remote mode
- add a defense-in-depth guard to skip kills in remote mode
- update remote-mode port diagnostics/reporting to match
- add regression coverage for Docker and local-mode behavior
- add a changelog entry for the fix

Co-Authored-By: ImLukeF <[email protected]>

* test: fix current ci regressions

* test: share outbound action runner helpers

* test: share telegram monitor startup helpers

* refactor: share self hosted provider plugin helpers

* test: share outbound delivery helpers

* refactor: share onboarding diagnostics type

* refactor: share delimited channel entry parsing

* refactor: share zalo send context validation

* refactor: share terminal note wrapping

* refactor: share tts request setup

* refactor: share gateway timeout parsing

* refactor: share session send context lines

* refactor: share memory tool builders

* refactor: share browser console result formatting

* refactor: share pinned sandbox entry finalization

* refactor: share tool result char estimation

* refactor: share agent tool fixture helpers

* test: share compaction retry timer helpers

* test: share embedded workspace attempt helpers

* refactor: share whatsapp outbound adapter base

* refactor: share zalo status issue helpers

* test: share whatsapp outbound poll fixtures

* refactor: share telegram reply chunk threading

* refactor: share daemon install cli setup

* fix: widen telegram reply progress typing

* refactor: share slack text truncation

* refactor: share allowlist wildcard matching

* refactor: declone model picker model ref parsing

* refactor: share dual text command gating

* test: share startup account lifecycle helpers

* test: share status issue assertion helpers

* fix: restore imessage control command flag

* test: share web fetch header helpers

* refactor: share session tool context setup

* test: share memory tool helpers

* refactor: share request url resolution

* Changelog: credit embedded runner queue deadlock fix

* fix(voicewake): avoid crash on foreign transcript ranges

* refactor(voicewake): mark transcript parameter unused

* docs(changelog): note voice wake crash fix

* fix: harden gateway status rpc smoke

* test: add parallels linux smoke harness

* fix(sessions): create transcript file on chat.inject when missing (openclaw#36645)

`chat.inject` called `appendAssistantTranscriptMessage` with
`createIfMissing: false`, causing a hard error when the transcript
file did not exist on disk despite having a valid `transcriptPath`
in session metadata. This commonly happens with ACP oneshot/run
sessions where the session entry is created but the transcript file
is not yet materialized.

The fix is a one-character change: `createIfMissing: true`. The
`ensureTranscriptFile` helper already handles directory creation
and file initialization safely.

Fixes openclaw#36170

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

* fix: harden discord guild allowlist resolution

* chore: update dependencies

* Plugins: fail fast on channel and binding collisions (openclaw#45628)

* Plugins: reject duplicate channel ids

* Bindings: reject duplicate adapter registration

* Plugins: fail on export id mismatch

* feat: add node-connect skill

* test: share directory runtime helpers

* refactor: share open allowFrom config checks

* test: share send cfg threading helpers

* refactor: reduce extension channel setup duplication

* refactor: share extension channel status summaries

* test: share feishu startup mock modules

* test: share plugin api test harness

* refactor: share extension monitor runtime setup

* refactor: share extension deferred and runtime helpers

* test: share sandbox fs bridge seeded workspace

* test: share subagent gateway mock setup

* test: share models config merge helpers

* test: share workspace skills snapshot helpers

* test: share context lookup helpers

* test: share timeout failover assertions

* test: share model selection config helpers

* test: share provider discovery auth fixtures

* test: share subagent announce timeout helpers

* test: share workspace skill test helpers

* refactor: share exec host approval helpers

* test: share oauth profile fixtures

* test: share memory search config helpers

* fix(macos): align minimum Node.js version with runtime guard (22.16.0) (openclaw#45640)

* macOS: align minimum Node.js version with runtime guard

* macOS: add boundary and failure-message coverage for RuntimeLocator

* docs: add changelog note for the macOS runtime locator fix

* credit: original fix direction from @sumleo, cleaned up and rebased in openclaw#45640 by @ImLukeF

* fix(agents): preserve blank local custom-provider API keys after onboarding

Co-authored-by: Xinhua Gu <[email protected]>

* fix(browser): harden existing-session driver validation and session lifecycle (openclaw#45682)

* fix(browser): harden existing-session driver validation, session lifecycle, and code quality

Fix config validation rejecting existing-session profiles that lack
cdpPort/cdpUrl (they use Chrome MCP auto-connect instead). Fix callTool
tearing down the MCP session on tool-level errors (element not found,
script error), which caused expensive npx re-spawns. Skip unnecessary
CDP port allocation for existing-session profiles. Remove redundant
ensureChromeMcpAvailable call in isReachable.

Extract shared ARIA role sets (INTERACTIVE_ROLES, CONTENT_ROLES,
STRUCTURAL_ROLES) into snapshot-roles.ts so both the Playwright and
Chrome MCP snapshot paths stay in sync. Add usesChromeMcp capability
flag and replace ~20 scattered driver === "existing-session" string
checks with the centralized flag.

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

* fix(browser): harden existing-session driver validation and session lifecycle (openclaw#45682) (thanks @odysseus0)

---------

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

* fix(ci): repair helper typing regressions

* fix: default Android TLS setup codes to port 443

* fix: unblock discord startup on deploy rate limits

* fix(feishu): add early event-level dedup to prevent duplicate replies (openclaw#43762)

* fix(feishu): add early event-level dedup to prevent duplicate replies

Add synchronous in-memory dedup at EventDispatcher handler level using
message_id as key with 5-minute TTL and 2000-entry cap.

This catches duplicate events immediately when they arrive from the Lark
SDK — before the inbound debouncer or processing queue — preventing the
race condition where two concurrent dispatches enter the pipeline before
either records the messageId in the downstream dedup layer.

Fixes the root cause reported in openclaw#42687.

* fix(feishu): correct inverted dedup condition

check() returns false on first call (new key) and true on subsequent
calls (duplicate). The previous `!check()` guard was inverted —
dropping every first delivery and passing all duplicates.

Remove the negation so the guard correctly drops duplicates.

* fix(feishu): simplify eventDedup key — drop redundant accountId prefix

eventDedup is already scoped per account (one instance per
registerEventHandlers call), so the accountId prefix in the cache key
is redundant. Use `evt:${messageId}` instead.

* fix(feishu): share inbound processing claim dedupe

---------

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

* fix(models): apply Gemini model-id normalization to google-vertex provider (openclaw#42435)

* fix(models): apply Gemini model-id normalization to google-vertex provider

The existing normalizeGoogleModelId() (which maps e.g. gemini-3.1-flash-lite
to gemini-3.1-flash-lite-preview) was only applied when the provider was
"google". Users configuring google-vertex/gemini-3.1-flash-lite would get
a "missing" model because the -preview suffix was never appended.

Extend the normalization to google-vertex in both model-selection
(parseModelRef path) and normalizeProviders (config normalization path).

Ref: openclaw#36838
Ref: openclaw#36918 (comment)


* fix(models): normalize google-vertex flash-lite

* fix(models): place unreleased changelog entry last

* fix(models): place unreleased changelog entry before releases

* fix(browser): add browser session selection

* build(android): add auto-bump signed aab release script

* build(android): strip unused dnsjava resolver service before R8

* test(discord): align rate limit error mock with carbon

* docs: fix changelog formatting

* fix: keep exec summaries inline

* build: shrink Android app release bundle

* Gateway: treat scope-limited probe RPC as degraded reachability (openclaw#45622)

* Gateway: treat scope-limited probe RPC as degraded

* Docs: clarify gateway probe degraded scope output

* test: fix CI type regressions in gateway and outbound suites

* Tests: fix Node24 diffs theme loading and Windows assertions

* Tests: fix extension typing after main rebase

* Tests: fix Windows CI regressions after rebase

* Tests: normalize executable path assertions on Windows

* Tests: remove duplicate gateway daemon result alias

* Tests: stabilize Windows approval path assertions

* Tests: fix Discord rate-limit startup fixture typing

* Tests: use Windows-friendly relative exec fixtures

---------

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

* build: upload Android native debug symbols

* fix(browser): prefer user profile over chrome relay

* chore: bump pi to 0.58.0

* test: harden parallels all-os smoke harness

* fix: keep windows onboarding logs ascii-safe

* docs: reorder unreleased changelog by impact

* build: prepare 2026.3.13-beta.1

* ci: add npm token fallback for npm releases

* fix(gateway): bound unanswered client requests (openclaw#45689)

* fix(gateway): bound unanswered client requests

* fix(gateway): skip default timeout for expectFinal requests

* fix(gateway): preserve gateway call timeouts

* fix(gateway): localize request timeout policy

* fix(gateway): clamp explicit request timeouts

* fix(gateway): clamp default request timeout

* Revert "Browser: scope nested batch failures in switch"

This reverts commit aaeb348.

* build: prepare 2026.3.13 release

* fix: keep android canvas home visible after restart

* chore: update appcast for 2026.3.13 release

* fix(browser): restore batch playwright dispatch

* feat(cron): support custom session IDs and auto-bind to current session (openclaw#16511)

feat(cron): support persistent session targets for cron jobs (openclaw#9765)

Add support for `sessionTarget: "current"` and `session:<id>` so cron jobs can
bind to the creating session or a persistent named session instead of only
`main` or ephemeral `isolated` sessions.

Also:
- preserve custom session targets across reloads and restarts
- update gateway validation and normalization for the new target forms
- add cron coverage for current/custom session targets and fallback behavior
- fix merged CI regressions in Discord and diffs tests
- add a changelog entry for the new cron session behavior

Co-authored-by: kkhomej33-netizen <[email protected]>
Co-authored-by: ImLukeF <[email protected]>

* test: harden parallels beta smoke flows

* build: prepare 2026.3.14 cycle

* build: sync plugins for 2026.3.14

* build: refresh lockfile for plugin sync

* fix(agents): normalize abort-wrapped RESOURCE_EXHAUSTED into failover errors (openclaw#11972)

* fix: move cause-chain traversal before timeout heuristic (review feedback)

* fix: harden wrapped rate-limit failover (openclaw#39820) thanks @lupuletic

* style: format probe regression test (openclaw#39820) thanks @lupuletic

* fix: tighten runner failover test types (openclaw#39820) thanks @lupuletic

* fix: annotate shared failover mocks (openclaw#39820) thanks @lupuletic

* test(ci): isolate cron heartbeat delivery cases

* fix(mattermost): carry thread context to non-inbound reply paths (openclaw#44283)

Merged via squash.

Prepared head SHA: 2846a6c
Co-authored-by: teconomix <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Reviewed-by: @mukhtharcm

* refactor: make OutboundSendDeps dynamic with channel-ID keys (openclaw#45517)

* refactor: make OutboundSendDeps dynamic with channel-ID keys

Replace hardcoded per-channel send fields (sendTelegram, sendDiscord,
etc.) with a dynamic index-signature type keyed by channel ID. This
unblocks moving channel implementations to extensions without breaking
the outbound dispatch contract.

- OutboundSendDeps and CliDeps are now { [channelId: string]: unknown }
- Each outbound adapter resolves its send fn via bracket access with cast
- Lazy-loading preserved via createLazySender with module cache
- Delete 6 deps-send-*.runtime.ts one-liner re-export files
- Harden guardrail scan against deleted-but-tracked files


* fix: preserve outbound send-deps compatibility

* style: fix formatting issues (import order, extra bracket, trailing whitespace)



* fix: resolve type errors from dynamic OutboundSendDeps in tests and extension

* fix: remove unused OutboundSendDeps import from deliver.test-helpers

* refactor(signal): move Signal channel code to extensions/signal/src/ (openclaw#45531)

Move all Signal channel implementation files from src/signal/ to
extensions/signal/src/ and replace originals with re-export shims.
This continues the channel plugin migration pattern used by other
extensions, keeping backward compatibility via shims while the real
code lives in the extension.

- Copy 32 .ts files (source + tests) to extensions/signal/src/
- Transform all relative import paths for the new location
- Create 2-line re-export shims in src/signal/ for each moved file
- Preserve existing extension files (channel.ts, runtime.ts, etc.)
- Change tsconfig.plugin-sdk.dts.json rootDir from "src" to "."
  to support cross-boundary re-exports from extensions/

* refactor: move iMessage channel to extensions/imessage (openclaw#45539)

* refactor: move WhatsApp channel implementation to extensions/ (openclaw#45725)

* refactor: move WhatsApp channel from src/web/ to extensions/whatsapp/

Move all WhatsApp implementation code (77 source/test files + 9 channel
plugin files) from src/web/ and src/channels/plugins/*/whatsapp* to
extensions/whatsapp/src/.

- Leave thin re-export shims at all original locations so cross-cutting
  imports continue to resolve
- Update plugin-sdk/whatsapp.ts to only re-export generic framework
  utilities; channel-specific functions imported locally by the extension
- Update vi.mock paths in 15 cross-cutting test files
- Rename outbound.ts -> send.ts to match extension naming conventions
  and avoid false positive in cfg-threading guard test
- Widen tsconfig.plugin-sdk.dts.json rootDir to support shim->extension
  cross-directory references

Part of the core-channels-to-extensions migration (PR 6/10).

* style: format WhatsApp extension files

* fix: correct stale import paths in WhatsApp extension tests

Fix vi.importActual, test mock, and hardcoded source paths that weren't
updated during the file move:
- media.test.ts: vi.importActual path
- onboarding.test.ts: vi.importActual path
- test-helpers.ts: test/mocks/baileys.js path
- monitor-inbox.test-harness.ts: incomplete media/store mock
- login.test.ts: hardcoded source file path
- message-action-runner.media.test.ts: vi.mock/importActual path

* refactor(slack): move Slack channel code to extensions/slack/src/ (openclaw#45621)

Move all Slack channel implementation files from src/slack/ to
extensions/slack/src/ and replace originals with shim re-exports.
This follows the extension migration pattern for channel plugins.

- Copy all .ts files to extensions/slack/src/ (preserving directory
  structure: monitor/, http/, monitor/events/, monitor/message-handler/)
- Transform import paths: external src/ imports use relative paths
  back to src/, internal slack imports stay relative within extension
- Replace all src/slack/ files with shim re-exports pointing to
  the extension copies
- Update tsconfig.plugin-sdk.dts.json rootDir from "src" to "." so
  the DTS build can follow shim chains into extensions/
- Update write-plugin-sdk-entry-dts.ts re-export path accordingly
- Preserve extensions/slack/index.ts, package.json, openclaw.plugin.json,
  src/channel.ts, src/runtime.ts, src/channel.test.ts (untouched)

* refactor: move Telegram channel implementation to extensions/ (openclaw#45635)

* refactor: move Telegram channel implementation to extensions/telegram/src/

Move all Telegram channel code (123 files + 10 bot/ files + 8 channel plugin
files) from src/telegram/ and src/channels/plugins/*/telegram.ts to
extensions/telegram/src/. Leave thin re-export shims at original locations so
cross-cutting src/ imports continue to resolve.

- Fix all relative import paths in moved files (../X/ -> ../../../src/X/)
- Fix vi.mock paths in 60 test files
- Fix inline typeof import() expressions
- Update tsconfig.plugin-sdk.dts.json rootDir to "." for cross-directory DTS
- Update write-plugin-sdk-entry-dts.ts for new rootDir structure
- Move channel plugin files with correct path remapping

* fix: support keyed telegram send deps

* fix: sync telegram extension copies with latest main

* fix: correct import paths and remove misplaced files in telegram extension

* fix: sync outbound-adapter with main (add sendTelegramPayloadMessages) and fix delivery.test import path

* refactor: move Discord channel implementation to extensions/ (openclaw#45660)

* refactor: move Discord channel implementation to extensions/discord/src/

Move all Discord source files from src/discord/ to extensions/discord/src/,
following the extension migration pattern. Source files in src/discord/ are
replaced with re-export shims. Channel-plugin files from
src/channels/plugins/*/discord* are similarly moved and shimmed.

- Copy all .ts source files preserving subdirectory structure (monitor/, voice/)
- Move channel-plugin files (actions, normalize, onboarding, outbound, status-issues)
- Fix all relative imports to use correct paths from new location
- Create re-export shims at original locations for backward compatibility
- Delete test files from shim locations (tests live in extension now)
- Update tsconfig.plugin-sdk.dts.json rootDir from "src" to "." to accommodate
  extension files outside src/
- Update write-plugin-sdk-entry-dts.ts to match new declaration output paths

* fix: add importOriginal to thread-bindings session-meta mock for extensions test

* style: fix formatting in thread-bindings lifecycle test

* refactor: remove channel shim directories, point all imports to extensions (openclaw#45967)

* refactor: remove channel shim directories, point all imports to extensions

Delete the 6 backward-compat shim directories (src/telegram, src/discord,
src/slack, src/signal, src/imessage, src/web) that were re-exporting from
extensions. Update all 112+ source files to import directly from
extensions/{channel}/src/ instead of through the shims.

Also:
- Move src/channels/telegram/ (allow-from, api) to extensions/telegram/src/
- Fix outbound adapters to use resolveOutboundSendDep (fixes 5 pre-existing TS errors)
- Update cross-extension imports (src/web/media.js → extensions/whatsapp/src/media.js)
- Update vitest, tsdown, knip, labeler, and script configs for new paths
- Update guard test allowlists for extension paths

After this, src/ has zero channel-specific implementation code — only the
generic plugin framework remains.

* fix: update raw-fetch guard allowlist line numbers after shim removal

* refactor: document direct extension channel imports

* test: mock transcript module in delivery helpers

* fix(zai): align explicit coding endpoint setup with detected model defaults (openclaw#45969)

* fix: align Z.AI coding onboarding with endpoint docs

* fix: align Z.AI coding onboarding with endpoint docs (openclaw#45969)

* docs: mark memory bootstrap change as breaking

* fix(ui): session dropdown shows label instead of key (openclaw#45130)

Merged via squash.

Prepared head SHA: 0255e39
Co-authored-by: luzhidong <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Reviewed-by: @altaywtf

* feat: add --force-document to message.send for Telegram (bypass sendPhoto + image optimizer) (openclaw#45111)

* feat: add --force-document to message.send for Telegram

Adds --force-document CLI flag to bypass sendPhoto and use sendDocument
instead, avoiding Telegram image compression for PNG/image files.

- TelegramSendOpts: add forceDocument field
- send.ts: skip sendPhoto when forceDocument=true (mediaSender pattern)
- ChannelOutboundContext: add forceDocument field
- telegramOutbound.sendMedia: pass forceDocument to sendMessageTelegram
- ChannelHandlerParams / DeliverOutboundPayloadsCoreParams: add forceDocument
- createChannelOutboundContextBase: propagate forceDocument
- outbound-send-service.ts: add forceDocument to executeSendAction params
- message-action-runner.ts: read forceDocument from params
- message.ts: add forceDocument to MessageSendParams
- register.send.ts: add --force-document CLI option

* fix: pass forceDocument through telegram action dispatch path

The actual send path goes through dispatchChannelMessageAction ->
telegramMessageActions.handleAction -> handleTelegramAction, not
deliverOutboundPayloads. forceDocument was not being read in
readTelegramSendParams or passed to sendMessageTelegram.

* fix: apply forceDocument to GIF branch to avoid sendAnimation

* fix: add disable_content_type_detection=true to sendDocument for --force-document

* fix: add forceDocument to buildSendSchema for agent discoverability

* fix: scope telegram force-document detection

* test: fix heartbeat target helper typing

* fix: skip image optimization when forceDocument is set

* fix: persist forceDocument in WAL queue for crash-recovery replay

* test: tighten heartbeat target test entry typing

---------

Co-authored-by: thepagent <[email protected]>
Co-authored-by: Frank Yang <[email protected]>

* Update CONTRIBUTING.md

* fix(build): update build:restart script to include ui:build step

* feat: add support for resolving implicit GitHub Copilot provider in narrative model compaction

* feat: execute beforeMessage and afterResponse hooks in RPC/embedded agent path

- Mount /rpc/agent/turn endpoint in server-http.ts (was defined but never registered)
- Run beforeMessage hook (WOL + KV cache restore) before LLM call in agentCommandInternal
- Run afterResponse hook (KV cache save) fire-and-forget after response
- Add afterResponse to AgentModelEntryConfig and AgentDefaultsConfig types + Zod schema

* feat(mind-memory): send desktop notifications on compaction and narrative regeneration

Adds sendNotify() helper (fire-and-forget via ~/scripts/notify.sh) and calls it
at the start and end of before_compaction and after_compaction hooks so the user
gets notified when Mind is compacting, updating STORY.md, and regenerating QUICK/SUMMARY.

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

* fix(status): use prompt fill (cacheRead+input) for context % and compact compaction label

---------

Co-authored-by: Robin Waslander <[email protected]>
Co-authored-by: Peter Steinberger <[email protected]>
Co-authored-by: Val Alexander <[email protected]>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: Frank Yang <[email protected]>
Co-authored-by: fabiaodemianyang <[email protected]>
Co-authored-by: Steven <[email protected]>
Co-authored-by: ImLukeF <[email protected]>
Co-authored-by: Sally O'Malley <[email protected]>
Co-authored-by: sallyom <[email protected]>
Co-authored-by: Jaehoon You <[email protected]>
Co-authored-by: Vincent Koc <[email protected]>
Co-authored-by: 2233admin <[email protected]>
Co-authored-by: Claude Opus 4.6 <[email protected]>
Co-authored-by: Ayaan Zaidi <[email protected]>
Co-authored-by: Xinhua Gu <[email protected]>
Co-authored-by: George Zhang <[email protected]>
Co-authored-by: yunweibang <[email protected]>
Co-authored-by: Tak Hoffman <[email protected]>
Co-authored-by: scoootscooob <[email protected]>
Co-authored-by: Muhammed Mukhthar CM <[email protected]>
Co-authored-by: Josh Avant <[email protected]>
Co-authored-by: Mainframe <[email protected]>
Co-authored-by: kkhomej33-netizen <[email protected]>
Co-authored-by: kkhomej33-netizen <[email protected]>
Co-authored-by: Catalin Lupuleti <[email protected]>
Co-authored-by: Darshil <[email protected]>
Co-authored-by: Teconomix <[email protected]>
Co-authored-by: teconomix <[email protected]>
Co-authored-by: mukhtharcm <[email protected]>
Co-authored-by: luzhidong <[email protected]>
Co-authored-by: luzhidong <[email protected]>
Co-authored-by: altaywtf <[email protected]>
Co-authored-by: thepagent <[email protected]>
Co-authored-by: thepagent <[email protected]>
Co-authored-by: Radek Sienkiewicz <[email protected]>
@mkamranawan891-tech
Copy link
Copy Markdown

My whatsapp +923058936258 open chat

@mkamranawan891-tech
Copy link
Copy Markdown

V2026.3.8
V2026.3.13

sbezludny pushed a commit to sbezludny/openclaw that referenced this pull request Mar 27, 2026
* UI: stop dashboard chat history reload storm

* Changelog: add PR number for chat reload fix

* fix: resolve branch typecheck regressions
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: web-ui App: web-ui channel: discord Channel integration: discord channel: matrix Channel integration: matrix channel: telegram Channel integration: telegram channel: tlon Channel integration: tlon channel: voice-call Channel integration: voice-call maintainer Maintainer-authored PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants