Skip to content

fix(matrix): split partial and quiet preview streaming#61450

Merged
gumadeiras merged 12 commits into
mainfrom
codex/matrix-quiet-preview-notifications
Apr 5, 2026
Merged

fix(matrix): split partial and quiet preview streaming#61450
gumadeiras merged 12 commits into
mainfrom
codex/matrix-quiet-preview-notifications

Conversation

@gumadeiras

@gumadeiras gumadeiras commented Apr 5, 2026

Copy link
Copy Markdown
Member

Summary

  • Problem: Matrix preview streaming used the same normal-text transport as finalized replies, so stock clients could notify on the first streamed preview token instead of the finished block or final reply.
  • Why it matters: Matrix needs two distinct behaviors: legacy visible preview-first delivery for existing installs, and a quiet preview path for self-hosted setups that want notifications only when a block or final reply is done.
  • What changed: channels.matrix.streaming now distinguishes "partial" and "quiet"; partial keeps the legacy visible preview behavior, quiet uses m.notice previews without mention metadata/link rendering, finalized quiet previews are marked explicitly, and quiet media captions now force the final edit before media delivery so final text semantics are preserved.
  • What did NOT change (scope boundary): default streaming: "off" behavior, normal finalized Matrix sends, and non-Matrix channels were not changed.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • 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 #
  • This PR fixes a bug or regression

Root Cause (if applicable)

  • Root cause: the Matrix draft-stream path coupled preview transport semantics to finalized-message semantics. Preview drafts reused normal m.text payload construction and mention-aware formatting, so previews could notify early and unchanged quiet media captions could skip the final edit that restores final-text semantics.
  • Missing detection / guardrail: tests covered mention metadata incompletely and did not lock in the unchanged-caption media finalize path for streaming: "quiet".
  • Contributing context (if known): existing partial behavior was already deployed, so the fix needed to separate quiet preview behavior without silently changing legacy preview-first installs.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: extensions/matrix/src/matrix/send.test.ts, extensions/matrix/src/matrix/draft-stream.test.ts, extensions/matrix/src/matrix/monitor/handler.test.ts, extensions/matrix/src/config-schema.test.ts
  • Scenario the test should lock in: partial previews stay legacy-visible, quiet previews suppress mentions and matrix.to links, finalized quiet edits carry the finalized-preview marker, and unchanged quiet media captions still force the final edit before media delivery.
  • Why this is the smallest reliable guardrail: the regression lives in Matrix payload construction plus draft/final handoff, so these focused tests exercise the exact seam without unrelated channel/runtime noise.
  • Existing test that already covers this (if any): none before this series.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • Matrix now supports channels.matrix.streaming: "quiet" in addition to "partial" and "off".
  • streaming: "partial" remains the legacy visible preview-first mode.
  • streaming: "quiet" creates quiet draft previews intended for self-hosted push-rule setups.
  • Quiet finalized previews now preserve final caption/text semantics even when the media caption text did not change.
  • Matrix docs now explain when to choose off, partial, or quiet, plus the push-rule setup needed for quiet finalized-preview notifications.

Diagram (if applicable)

Before:
[stream token] -> [normal preview event] -> [early client notification]
[quiet media final with unchanged caption] -> [skip final edit] -> [preview semantics leak into final]

After:
[stream token] -> [partial preview OR quiet notice]
[block/final boundary] -> [final edit or normal send] -> [expected notification boundary]

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local Node/pnpm repo environment
  • Model/provider: N/A
  • Integration/channel (if any): Matrix bundled plugin
  • Relevant config (redacted): verified channels.matrix.streaming in "partial", "quiet", and "off"-compatible paths through targeted Matrix tests; verified both blockStreaming: true and blockStreaming: false where covered by the touched suite

Steps

  1. Enable Matrix preview streaming and trigger a reply that streams text.
  2. Compare visible preview payloads and finalized delivery behavior for streaming: "partial" vs streaming: "quiet".
  3. Exercise a media reply whose final caption text matches the last quiet draft preview.

Expected

  • partial preserves legacy visible preview-first behavior.
  • quiet previews stay non-notifying and finalized quiet edits preserve final text semantics.
  • Media captions are not dropped or left with preview-only semantics when the final caption text is unchanged.

Actual

  • partial remains visible-preview mode.
  • quiet previews use the quiet draft path with explicit finalized-preview edits.
  • Unchanged quiet media captions now force the final edit before media delivery.

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: exact targeted Matrix lane covering send payloads, draft-stream behavior, finalize/reuse logic, quiet media captions, and config-schema acceptance.
  • Edge cases checked: partial vs quiet, finalized-preview metadata, mention/link suppression, no-op partial final edits, unchanged quiet media captions, blockStreaming-related touched flows.
  • What you did not verify: live Matrix clients end-to-end across homeservers/clients; repo-wide pnpm check / full suite, per current prep scope, because unrelated baseline failures exist outside this PR surface.

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:

Risks and Mitigations

  • Risk: users may choose streaming: "quiet" expecting stock-client notifications without configuring recipient push rules.
    • Mitigation: docs now make off vs partial vs quiet explicit and mark quiet mode as the push-rule path.
  • Risk: finalization regressions could reappear when preview text matches the final text exactly.
    • Mitigation: targeted handler coverage now locks in the unchanged-caption quiet media path and the no-op partial final-edit path separately.

Copilot AI review requested due to automatic review settings April 5, 2026 17:41
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: matrix Channel integration: matrix size: M maintainer Maintainer-authored PR labels Apr 5, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes Matrix streaming: "partial" preview events inadvertently triggering notifications by sending drafts as quiet m.notice messages without mention metadata/links, while ensuring finished blocks/final replies are delivered via the normal Matrix send path and stale previews get redacted afterward.

Changes:

  • Add msgtype + includeMentions controls to Matrix text send/edit formatting to support “quiet” drafts.
  • Update Matrix draft streaming to always emit previews as m.notice with mentions disabled.
  • Simplify draft finalization in the monitor handler: deliver finals normally and redact the preview event.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
extensions/matrix/src/matrix/send/types.ts Introduces MatrixTextMsgType (m.text/m.notice) for configurable text sends.
extensions/matrix/src/matrix/send/formatting.ts Adds mention-free HTML rendering path and supports configurable msgtype.
extensions/matrix/src/matrix/send.ts Threads msgtype/includeMentions through single-send and edit paths; avoids mention diff work when mentions disabled.
extensions/matrix/src/matrix/send.test.ts Adds coverage for quiet preview sends/edits (no m.mentions, no matrix.to links).
extensions/matrix/src/matrix/monitor/handler.ts Changes finalize behavior to always do normal delivery + redact preview drafts.
extensions/matrix/src/matrix/monitor/handler.test.ts Updates expectations for new finalize/redaction behavior in draft streaming scenarios.
extensions/matrix/src/matrix/draft-stream.ts Forces draft previews to m.notice and disables mentions in preview sends/edits.
extensions/matrix/src/matrix/draft-stream.test.ts Asserts preview msgtype is m.notice and lacks mention metadata.
docs/channels/matrix.md Documents that partial draft previews are quiet notices (notifications at block/final boundaries).

Comment thread extensions/matrix/src/matrix/monitor/handler.test.ts

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

Copy link
Copy Markdown

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: 70d97bce84

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/monitor/handler.ts Outdated
@greptile-apps

greptile-apps Bot commented Apr 5, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a real and impactful bug: with streaming: \"partial\", the first streamed preview was sent as a regular m.text event with full mention metadata, causing Matrix clients to notify users on the first streamed token rather than waiting for a completed block or final reply.

The fix has two parts:

  • Draft preview path (draft-stream.ts, send.ts, send/formatting.ts): preview sends and edits now always use m.notice msgtype with includeMentions: false, stripping both the m.mentions metadata and matrix.to mention links from the HTML body.
  • Finalization path (monitor/handler.ts): the old "finalize in place" logic (edit draft → become final message) is replaced with a simpler, always-correct flow: deliverMatrixReplies for every final/block delivery (proper notifying m.text event), then redact the stale m.notice draft. This costs ~1–2 extra API calls per block, but eliminates all conditional branching around mustDeliverFinalNormally, draftConsumed, payloadReplyMismatch, and the editMessageMatrix fast-path.

One issue found: In handler.test.ts, the test \"redacts stale draft and sends the final once when a later preview exceeds the event limit\" had its expect(redactEventMock).toHaveBeenCalledWith(...) assertion dropped. The production code correctly redacts $draft1 in this case — currentEventId is not cleared on overflow, only stopped is set — but the test no longer verifies it, leaving a coverage gap.

Confidence Score: 4/5

Safe to merge; the production logic is correct and the fix addresses the real notification bug.

The core change (m.notice + always-redact-then-deliver) is logically sound and well-tested overall. The one identified issue is a missing test assertion in the overflow scenario — the production code behaves correctly (redaction still happens), but the assertion was accidentally dropped, leaving a blind spot for future regressions. All other aspects of the PR — the m.notice/includeMentions plumbing in send.ts/formatting.ts, the draft-stream simplification, and the handler deliver-callback rewrite — are clean and the test updates correctly reflect the new behavior.

extensions/matrix/src/matrix/monitor/handler.test.ts — the overflow test at line 2126 needs its redactEventMock assertion restored.

Comments Outside Diff (1)

  1. extensions/matrix/src/matrix/monitor/handler.test.ts, line 2126-2152 (link)

    P1 Missing redaction assertion after overflow: test name says "redacts stale draft" but assertion was dropped

    The test name is still "redacts stale draft and sends the final once when a later preview exceeds the event limit", but the expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1") assertion was removed in this PR.

    Tracing the code path:

    1. onPartialReply({ text: "1234" }) succeeds and sets currentEventId = "$draft1".
    2. The overflow mock is applied; draftStream.stop() calls loop.flush(), which triggers sendOrEdit("123456").
    3. sendOrEdit hits fitsInSingleEvent: false, sets stopped = true, and returns — without clearing currentEventId.
    4. Back in the handler, draftStream.eventId() returns "$draft1", so the if (draftEventId) branch is entered and client.redactEvent(roomId, "$draft1") IS called.

    The production code is correct, but the test no longer asserts the redaction, leaving a regression gap.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: extensions/matrix/src/matrix/monitor/handler.test.ts
    Line: 2126-2152
    
    Comment:
    **Missing redaction assertion after overflow: test name says "redacts stale draft" but assertion was dropped**
    
    The test name is still `"redacts stale draft and sends the final once when a later preview exceeds the event limit"`, but the `expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1")` assertion was removed in this PR.
    
    Tracing the code path:
    1. `onPartialReply({ text: "1234" })` succeeds and sets `currentEventId = "$draft1"`.
    2. The overflow mock is applied; `draftStream.stop()` calls `loop.flush()`, which triggers `sendOrEdit("123456")`.
    3. `sendOrEdit` hits `fitsInSingleEvent: false`, sets `stopped = true`, and returns — **without clearing `currentEventId`**.
    4. Back in the handler, `draftStream.eventId()` returns `"$draft1"`, so the `if (draftEventId)` branch is entered and `client.redactEvent(roomId, "$draft1")` IS called.
    
    The production code is correct, but the test no longer asserts the redaction, leaving a regression gap.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/matrix/src/matrix/monitor/handler.test.ts
Line: 2126-2152

Comment:
**Missing redaction assertion after overflow: test name says "redacts stale draft" but assertion was dropped**

The test name is still `"redacts stale draft and sends the final once when a later preview exceeds the event limit"`, but the `expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1")` assertion was removed in this PR.

Tracing the code path:
1. `onPartialReply({ text: "1234" })` succeeds and sets `currentEventId = "$draft1"`.
2. The overflow mock is applied; `draftStream.stop()` calls `loop.flush()`, which triggers `sendOrEdit("123456")`.
3. `sendOrEdit` hits `fitsInSingleEvent: false`, sets `stopped = true`, and returns — **without clearing `currentEventId`**.
4. Back in the handler, `draftStream.eventId()` returns `"$draft1"`, so the `if (draftEventId)` branch is entered and `client.redactEvent(roomId, "$draft1")` IS called.

The production code is correct, but the test no longer asserts the redaction, leaving a regression gap.

```suggestion
    expect(editMessageMatrixMock).not.toHaveBeenCalled();
    expect(redactEventMock).toHaveBeenCalledWith("!room:example.org", "$draft1");
    expect(deliverMatrixRepliesMock).toHaveBeenCalledTimes(1);
    expect(sendSingleTextMessageMatrixMock).toHaveBeenCalledTimes(1);
    await finish();
```

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

Reviews (1): Last reviewed commit: "fix(matrix): quiet streamed preview noti..." | Re-trigger Greptile

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

Copy link
Copy Markdown

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: eec8db093f

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/draft-stream.ts Outdated

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

Copy link
Copy Markdown

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: a3c242f921

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/monitor/handler.ts Outdated

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

Copy link
Copy Markdown

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: fc652766cb

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/monitor/handler.ts
@gumadeiras gumadeiras self-assigned this Apr 5, 2026

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

Copy link
Copy Markdown

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: e0955d3ebc

ℹ️ About Codex in GitHub

Your team has set up Codex to 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 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/matrix/src/matrix/monitor/handler.ts Outdated
@gumadeiras gumadeiras force-pushed the codex/matrix-quiet-preview-notifications branch 2 times, most recently from 1a779b6 to 8f4fb5d Compare April 5, 2026 22:07
@gumadeiras gumadeiras force-pushed the codex/matrix-quiet-preview-notifications branch from 8f4fb5d to 22692cf Compare April 5, 2026 22:07
@gumadeiras gumadeiras changed the title fix(matrix): quiet streamed preview notifications fix(matrix): split partial and quiet preview streaming Apr 5, 2026
@gumadeiras gumadeiras merged commit 8a841b5 into main Apr 5, 2026
9 checks passed
@gumadeiras gumadeiras deleted the codex/matrix-quiet-preview-notifications branch April 5, 2026 22:23
@gumadeiras

Copy link
Copy Markdown
Member Author

Merged via squash.

Thanks @gumadeiras!

Caocaoha added a commit to Caocaoha/openclaw that referenced this pull request Apr 8, 2026
* feat(memory-wiki): add import gateway methods

* feat(memory-wiki): add shared memory search bridge

* feat(memory-wiki): add prompt supplement integration

* feat(memory-wiki): surface imported source provenance

* feat(memory-wiki): lint imported provenance gaps

* feat(memory-wiki): allow per-call search corpus overrides

* feat(memory-core): bridge wiki corpus into memory tools

* feat(memory-wiki): compile related backlinks blocks

* docs(memory-wiki): prefer shared corpus recall guidance

* docs(memory-wiki): document shared recall and backlinks

* feat(memory-wiki): generate dashboard report pages

* test: isolate exec approval suite from bundled plugins

* fix(sandbox): harden EXDEV rename fallback

* Gateway: keep outbound session metadata in owner store

* revert(memory-wiki): back out llm wiki stack

* fix: align models status provider auth reporting

* fix(ci): narrow control ui locale refresh push runs

* style: format remaining local edits

* fix: prevent duplicate block reply delivery for text_end channels (openclaw#61530)

* fix(gateway): bound silent local pairing scopes

* fix: resolve repo check drift

* fix: clean rebase leftovers

* test: isolate agent runtime seams

* docs: refine unreleased changelog

* feat(video): add xai and alibaba providers

* Revert "fix(gateway): bound silent local pairing scopes"

This reverts commit 7f1b159.

* fix(build): correct node require typing

* docs(security): clarify localhost shared-auth trust model

* refactor: move browser runtime seams behind plugin metadata

* test: speed up provider policy and auth suites

* Memory: move dreaming trail to dreams.md (openclaw#61537)

* Memory: move dreaming trail to dreams.md

* docs(changelog): add dreams.md entry

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>

* fix(ci): stabilize ui i18n and gateway watch checks

* docs(providers): add generation setup pages

* docs(providers): link generation guides

* feat: add qa channel foundation

* refactor: hide qa channels with exposure metadata

* feat: add qa lab extension

* chore: polish qa lab follow-ups

* feat(qa): recreate qa lab docker stack

* fix(qa): restore embedded control ui gateway startup

* fix(qa): stabilize docker gateway bootstrap

* feat(qa): add repo-backed qa suite runner

* fix(qa): stabilize hermetic suite runtime

* fix(matrix): split partial and quiet preview streaming (openclaw#61450)

Merged via squash.

Prepared head SHA: 6a0d7d1
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras

* docs(providers): unify qwen docs

* fix(matrix): honor canonical private-network opt-in

* fix(matrix): restore cli metadata registrar

* test(matrix): isolate migration snapshot seam

* fix: prevent duplicate gateway watchers

* feat(memory-core): add REM preview and safe promotion replay (openclaw#61540)

* memory: add REM preview and safe promotion replay thanks @mbelinky

* changelog: note REM preview and promotion replay

---------

Co-authored-by: Vignesh <mailvgnsh@gmail.com>

* test: fix abort cascade and workspace edit inputs

* refactor: harden plugin metadata and browser sdk seams

* fix(memory-core): preserve dated DREAMS trail

* docs(memory): point dreaming trail docs to dreams.md

* fix(memory): standardize DREAMS trail path

* fix(google): restore gemini cli provider contract

* test(contracts): drop removed claude cli auth export

* test(config): align markdown tables with active registry

* style(tests): normalize registry mock wrapping

* fix: normalize video provider durations

* fix: harden video provider transports

* fix: honor discord allowlisted channels for native commands

* fix: bootstrap pnpm for git updates

* docs: add tahoe release-to-dev smoke lane

* test: isolate openclaw plugin context coverage

* test: stabilize subagent persistence registry coverage

* test: isolate gateway tool coverage

* fix: surface normalized video durations

* fix(google): restore forward-compat provider hooks

* test(config): fix markdown table mock typing

* test: drop redundant openai extra params coverage

* refactor: dedupe discord native command auth

* docs: add discord native command changelog note

* fix(video): queue fal provider jobs

* feat(agents): track video generation tasks

* fix(discord): short-circuit bound thread self-loop drops

* refactor: harden plugin metadata and bundled channel entry seams

* test: fold xai extra params coverage into hot lane

* fix: ignore unsupported image generation overrides

* docs: document channel persisted auth metadata

* test(live): prefer google models over big-pickle

* Lobster: run workflows in process (openclaw#61523)

* Lobster: run workflows in process

* docs: note in-process lobster runtime

* docs: add lobster changelog attribution

* Lobster: add managed TaskFlow mode (openclaw#61555)

* test: split inline provider model coverage

* docs: update Lobster in-process mode and REM preview tooling

* test: speed up nodes camera coverage

* fix: defer plugin sync after git switch

* test: optimize macos release-to-dev smoke lane

* fix(openai): avoid em dashes in gpt-5 overlay (openclaw#61560)

* feat(agents): detach video generation completion

* feat(video): add runway provider

* docs(video): document runway support

* fix: clarify dirty dev update error

* fix: ignore unsupported video generation overrides

* refactor: add metadata-first channel configured-state probes

* fix(video): guard active async generation tasks

* docs(providers): surface new video provider pages

* feat(qa): add live suite runner and harness

* feat(qa): improve qa lab debugger ui

* fix: restore pnpm check type safety

* test: trim slow agent web and lifecycle coverage

* fix: restore green checks

* fix(qa): stop embedded control ui reload loop

* test: reset guest git root before dev update

* test: speed up openai tool id preservation replay coverage

* fix: restore qa lab config typing

* matrix: align bundled channel metadata

* docs: note Matrix persisted auth detection

* docs: add changelog note for qa lab config fix

* refactor(video): share async task status helpers

* memory-core: checkpoint mode-first dreaming refactor

* Dreaming: simplify sweep flow and add diary surface

* docs: rewrite video generation docs for readability

* docs(faq): add gpt-5.4 fast mode entry

* feat(memory): add Bedrock embedding provider for memory search (openclaw#61547)

* feat(memory): add Bedrock embedding provider for memory search

Add Amazon Bedrock as a native embedding provider for memory search.
Supports Titan Embed Text v1/v2 and Cohere Embed models via AWS SDK.

- New embeddings-bedrock.ts: BedrockRuntimeClient + InvokeModel
- Auth via AWS default credential chain (same as Bedrock inference)
- Auto-selected in 'auto' mode when AWS credentials are detected
- Titan V2: configurable dimensions (256/512/1024), normalization
- Cohere: native batch support with search_query/search_document types
- 16 new tests covering all model types, auth detection, edge cases

Closes openclaw#26289

* fix(memory): harden bedrock embedding selection

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>

* docs(openai): clarify gpt-5.4 fast mode

* test: speed up models config env provider coverage

* test: speed up sanitize session history policy smoke

* build: refresh lockfile for control ui deps

* refactor: narrow bundled channel entry surfaces

* test: speed up sanitize session history coverage

* fix: skip old-process config writes after git switch

* fix(update): bootstrap pnpm for dev preflight

* fix(memory-qmd): restore qmd compatibility defaults

* test: speed up image tool auth-heavy coverage

* test: seed channel setup contract registry in helper tests

* Dreaming: update multiphase stats and UI polish

* test: add irc runtime api smoke coverage

* feat(bedrock-mantle): add IAM credential auth via @aws/bedrock-token-… (openclaw#61563)

* feat(bedrock-mantle): add IAM credential auth via @aws/bedrock-token-generator

Mantle previously required a manually-created API key (AWS_BEARER_TOKEN_BEDROCK).
This adds automatic bearer token generation from IAM credentials using the
official @aws/bedrock-token-generator package.

Auth priority:
1. Explicit AWS_BEARER_TOKEN_BEDROCK env var (manual API key from Console)
2. IAM credentials via getTokenProvider() → Bearer token (instance roles,
   SSO profiles, access keys, EKS IRSA, ECS task roles)

Token is cached in memory (1hr TTL, generated with 2hr validity) and in
process.env.AWS_BEARER_TOKEN_BEDROCK for downstream sync reads.

Falls back gracefully when package is not installed or credentials are
unavailable — Mantle provider simply not registered.

Closes openclaw#45152

* fix(bedrock-mantle): harden IAM auth

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>

* refactor(update): extract package manager bootstrap logic

* feat: add comfy workflow media support

* fix: stabilize line and feishu ci shards

* feat: add music generation tooling

* chore: remove stray finder metadata

* docs: document music generation async flow

* fix(memory-qmd): streamline compatibility coverage

* test: speed up dispatch-from-config thread fallback coverage

* docs: improve music generation docs

* docs: reorder changelog highlights

* fix: skip stale post-switch update follow-ups

* test: harden macos release-to-dev smoke verification

* fix: route comfy music through shared tool

* refactor: remove comfy music tool shim

* Gateway: bound websocket shutdown close (openclaw#61565)

Merged via squash.

Prepared head SHA: 9040dd5
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky

* Docs: clarify Matrix quiet push rules

* memory: chunk daily dreaming ingestion (openclaw#61583)

Merged via squash.

Prepared head SHA: 88816a0
Co-authored-by: mbelinky <17249097+mbelinky@users.noreply.github.com>
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky

* fix: stop old cli after package-to-git switch

* fix(gateway): accept music generation internal events

* docs: update unreleased provider notes

* fix(agents): keep large read tool results visible

* feat: add vydra media provider

* fix(agents): ignore unsupported music generation hints

* fix(agents): preserve latest read output during compaction

* docs: update changelog for read visibility fixes

* test: fix current-main prep blockers (openclaw#61582)

Merged via squash.

Prepared head SHA: 49f7b12
Reviewed-by: @mbelinky

* test: use explicit node entrypoint in macos update smoke

* fix: exit after package-to-git handoff

* fix: prune staged feishu sdk types from npm pack

* fix(qa): harden new scenario suite

* fix(agents): prefer overflow compaction for fresh reads

* perf(auto-reply): lazy-load TTS helpers on demand

* test(plugin-sdk): tighten ACP command dispatch guards

* docs(web): clarify control ui language picker

* test(auto-reply): split ACP and reply-dispatch regressions

* memory: trim generic daily chunk headings (openclaw#61597)

* memory: trim generic daily chunk headings

* docs: tag dreaming heading cleanup changelog

* docs: attribute dreaming heading cleanup changelog

* fix(cli): narrow post-update root

* fix(ui): localize control ui strings

* Lobster: harden embedded runtime integration (openclaw#61566)

Merged via squash.

Prepared head SHA: a6f4830
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky

* fix(matrix): reuse raw default account key during onboarding promotion

* fix: unblock comfy live plugin loading

* fix(agents): extend subagent announce timeout

* fix(agents): carry async media wake attachments structurally

* fix(tasks): hide internal completion wake rows

* test(auto-reply): isolate reply abort dispatch seams

* test: fix reply dispatch mock contract

* fix(ui): localize more control ui strings

* fix: deliver async media generation results directly

* perf(test): trim send-policy and abort hot paths

* perf(agents): isolate subagent announce origin helper

* fix(discord): raise default media cap

* Matrix: recover from pinned dispatcher runtime failures (openclaw#61595)

Merged via squash.

Prepared head SHA: f9a2d9b
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras

* fix: harden async media completion delivery

* fix: gate async media direct delivery behind config

* docs: add changelog note for async media delivery flag

* perf(test): trim announce and sessions tool imports

* fix: resolve global bundled plugin facade fallback (openclaw#61297) (thanks @openperf)

* fix(gateway): resolve globally-installed bundled plugins in facade-runtime

* fix: resolve global bundled plugin facade fallback (openclaw#61297) (thanks @openperf)

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>

* chore: prepare 2026.4.6-beta.1 release

* style: trim facade fallback comment noise

* test: stabilize browser and provider ci shards

* fix: restore latest-main ci gates

* (chore): delete dream-diary-preview file

* perf(test): trim runReplyAgent misc mock imports

* fix(ci): harden control ui locale refresh rebases

* Matrix: clear undici test override after transport test

* chore(ui): refresh zh-CN control ui locale

* chore(ui): refresh pt-BR control ui locale

* chore(ui): refresh zh-TW control ui locale

* chore(ui): refresh de control ui locale

* fix: support corepack cmd shim on windows

* test: add windows dev-update smoke lanes

* chore(ui): refresh es control ui locale

* chore(ui): refresh ja-JP control ui locale

* chore(ui): refresh ko control ui locale

* chore(ui): refresh fr control ui locale

* test: capture windows npm debug tails in smoke logs

* chore(ui): refresh tr control ui locale

* chore(ui): refresh uk control ui locale

* chore(ui): refresh id control ui locale

* chore(ui): refresh pl control ui locale

* fix: restore plugin boundary and ui locale ci gates

* fix(ci): stabilize control ui locale checks

* chore: release 2026.4.5

* perf(test): split subagent command coverage

* fix(ci): patch main regression surfaces

* fix: install bun in npm release preflight

* test: fix subagent command result assertions

* perf(test): split allowlist and models command coverage

* fix(openai): allow qa image generation mock routing

* feat(qa): execute ten new repo-backed scenarios

* fix(matrix): harden startup auth bootstrap (openclaw#61383)

Merged via squash.

Prepared head SHA: d8011a9
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras

* Docs: clarify Matrix autoJoin invite scope

* fix(discord): narrow binding runtime imports

* fix: stabilize contract loader seams

* test: tighten allowlist fixture typing

* fix(qa): support image understanding inputs

* feat(qa): add attachment understanding scenario

* docs(matrix): clarify historyLimit default

* feat(memory-wiki): restore llm wiki stack

* chore: update appcast for 2026.4.5

* perf(test): split reply command coverage

* perf(reply): lazy load compact runtime

* refactor(reply): extract subagent text helper

* style(reply): normalize subagent import order

* fix: restore protocol and extension ci

* chore: bump version to 2026.4.6

* fix(config): normalize channel streaming config shape (openclaw#61381)

* feat(config): add canonical streaming config helpers

* refactor(runtime): prefer canonical streaming accessors

* feat(config): normalize preview channel streaming shape

* test(config): lock streaming normalization followups

* fix(config): polish streaming migration edges

* chore(config): refresh streaming baseline hash

* docs(memory): add promote-explain and rem-harness CLI reference

* build: refresh pnpm lockfile

* fix: stop emitting post-background exec updates (openclaw#61627) (thanks @openperf)

* fix(exec ): stop emitting tool updates after session is backgrounded

When an exec session is backgrounded (background: true), the owning
agent run resolves its tool-call promise and may finish.  The stdout
handler's emitUpdate() closure, however, kept invoking opts.onUpdate(),
delivering tool_execution_update events to a listener whose active run
had already ended.  This surfaced as an unhandled rejection and crashed
the gateway process.

Guard emitUpdate() with a session.backgrounded || session.exited check
so that post-background output is still captured via appendOutput() but
no longer forwarded to the (now-stale) agent-loop callback.

Fixes openclaw#61592

* style: trim exec backgrounding comments

* fix: stop emitting post-background exec updates (openclaw#61627) (thanks @openperf)

* fix: place exec changelog entry at end of fixes (openclaw#61627) (thanks @openperf)

---------

Co-authored-by: Ayaan Zaidi <hi@obviy.us>

* test(memory-core): align dreaming expectations

* test(memory-wiki): share plugin test helpers

* test(memory-core): share workspace test helper

* test(memory-core): reuse narrative workspace helper

* test(plugin-sdk): share temp dir test helper

* test(plugin-sdk): reuse temp dir helpers in facade tests

* test(memory-core): reuse workspace helper in dreaming tests

* perf(agents): add continuation-skip context injection (openclaw#61268)

* test(agents): cover continuation bootstrap reuse

* perf(agents): add continuation-skip context injection

* docs(changelog): note context injection reuse

* perf(agents): bound continuation bootstrap scan

* fix(agents): require full bootstrap proof for continuation skip

* fix(agents): decide continuation skip under lock

* fix(commands): re-export subagent chat message type

* fix(agents): clean continuation rebase leftovers

* test(memory-core): reuse workspace helper in temp dir tests

* docs: add contextInjection config key to reference

* feat(gateway): preserve session history on /new command

Backend changes for session sidebar feature:
- session.ts: create compound key entry for old session when /new triggered
- agent.ts: pass preserveHistory=true to session reset
- session-reset-service.ts: add file reuse optimization for preserved sessions
- types.ts: add previousSessionKey field to SessionEntry
- session-utils.ts: add compound key support in session key resolution

This enables the UI to show previous sessions in sidebar while
preserving complete chat history for archived sessions.

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
Co-authored-by: Tyler Yust <64381258+tyler6204@users.noreply.github.com>
Co-authored-by: Dave Morin <dave@morin.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: Mariano <132747814+mbelinky@users.noreply.github.com>
Co-authored-by: Vignesh <mailvgnsh@gmail.com>
Co-authored-by: Vignesh Natarajan <vignesh.natarajan92@gmail.com>
Co-authored-by: wirjo <daniel@wirjo.com>
Co-authored-by: Mariano <mbelinky@gmail.com>
Co-authored-by: mbelinky <17249097+mbelinky@users.noreply.github.com>
Co-authored-by: Chunyue Wang <80630709+openperf@users.noreply.github.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: OpenClaw Agent <caoha@openclaw.ai>
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
Merged via squash.

Prepared head SHA: 6a0d7d1
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
Merged via squash.

Prepared head SHA: 6a0d7d1
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
Merged via squash.

Prepared head SHA: 6a0d7d1
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
Merged via squash.

Prepared head SHA: 6a0d7d1
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: matrix Channel integration: matrix docs Improvements or additions to documentation maintainer Maintainer-authored PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants