Skip to content

Lobster: harden embedded runtime integration#61566

Merged
mbelinky merged 2 commits into
mainfrom
pr/lobster-greptile-harden
Apr 6, 2026
Merged

Lobster: harden embedded runtime integration#61566
mbelinky merged 2 commits into
mainfrom
pr/lobster-greptile-harden

Conversation

@mbelinky

@mbelinky mbelinky commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Problem: the new in-process Lobster integration still had a few follow-up hardening gaps from Greptile review.
  • Why it matters: managed TaskFlow resume mode could accept incomplete resume params, the embedded runtime loader did unnecessary work on every tool call, and the duplicated TaskFlow test mock could drift.
  • What changed: managed resume mode now requires token and approve, the embedded runtime is memoized per runner and resolves the installed Lobster package root without fixed path arithmetic, and the shared TaskFlow test mock now lives in one helper.
  • What did NOT change (scope boundary): no changes in src/tasks/**, src/plugins/runtime/**, or Lobster core itself.

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

Root Cause / Regression History (if applicable)

  • Root cause: the first two Lobster PRs landed the main transport and TaskFlow changes, but left a few correctness and maintainability gaps in the plugin seam.
  • Missing detection / guardrail: managed resume mode did not have coverage for missing token / approve, and the embedded runner had no regression test asserting runtime memoization.
  • Prior context (git blame, prior PR, issue, or refactor if known): this follows up on Greptile review feedback from Lobster: run workflows in process #61523 and Lobster: add managed TaskFlow mode #61555.
  • Why this regressed now: the earlier PRs were intentionally kept tight to land the transport and TaskFlow slices first.
  • If unknown, what was ruled out: N/A

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/lobster/src/lobster-runner.test.ts
    • extensions/lobster/src/lobster-tool.test.ts
    • extensions/lobster/src/lobster-taskflow.test.ts
  • Scenario the test should lock in: managed resume mode rejects incomplete resume params, embedded runtime loading is memoized per runner, and TaskFlow tests share one mock helper.
  • Why this is the smallest reliable guardrail: the changed behavior is fully inside the Lobster plugin seam.
  • Existing test that already covers this (if any): earlier Lobster tests covered the happy paths, but not these follow-up edge cases.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • Managed Lobster resume calls now fail fast if token or approve is missing.
  • Repeated Lobster tool invocations on the same runner no longer reload the embedded runtime.

Diagram (if applicable)

Before:
[lobster tool] -> [validate some flow params] -> [load embedded runtime every call]

After:
[lobster tool] -> [validate complete managed resume params] -> [reuse embedded runtime per runner]

Security Impact (required)

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

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: local Node/pnpm workspace in a clean worktree
  • Model/provider: N/A
  • Integration/channel (if any): Lobster bundled plugin
  • Relevant config (redacted): default local test config

Steps

  1. Run targeted Lobster Vitest coverage for runner/tool/taskflow.
  2. Run Oxlint on the touched Lobster files.
  3. Run pnpm build.

Expected

  • Lobster hardening changes pass targeted plugin tests and lint.
  • Build should stay green unless current main already has an unrelated failure.

Actual

  • Targeted Lobster tests passed.
  • Oxlint passed.
  • pnpm build failed in untouched Pi runner code on current main:
    • src/agents/pi-embedded-runner/model.ts(516,11): error TS2304: Cannot find name 'DEFAULT_CONTEXT_TOKENS'.
    • src/agents/pi-embedded-runner/model.ts(521,11): error TS2304: Cannot find name 'DEFAULT_CONTEXT_TOKENS'.

Evidence

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

Human Verification (required)

  • Verified scenarios:
    • managed resume rejects missing token
    • managed resume rejects missing approve
    • embedded runtime loads once per runner
    • shared TaskFlow mock still supports tool/taskflow tests
  • Edge cases checked:
    • runtime loader failure still remains retryable because the memoized promise resets on rejection
  • What you did not verify:
    • no full green build because current main fails in untouched Pi runner code

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.

Compatibility / Migration

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

Risks and Mitigations

  • Risk:

    • Memoizing the embedded runtime could retain a failed load forever.
    • Mitigation:
      • the cached promise is cleared on rejection so later calls can retry.
  • Risk:

    • Tightening managed resume validation could reject callers that relied on deferred runner errors.
    • Mitigation:
      • this only affects invalid calls and now fails earlier with clearer error messages.

AI Assistance

  • AI-assisted: yes
  • Testing: targeted vitest, oxlint, build attempt

@openclaw-barnacle openclaw-barnacle Bot added extensions: lobster Extension: lobster size: M maintainer Maintainer-authored PR labels Apr 6, 2026
@greptile-apps

greptile-apps Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR hardens the embedded Lobster runtime integration across three areas: managed TaskFlow resume mode now validates that token and approve are both present before entering the managed path (failing fast with actionable errors instead of propagating missing fields to the runner); the embedded runtime is memoized per runner instance via runtimePromise ??= ... with promise-reset on failure to allow retry; and the createFakeTaskFlow mock is extracted into a shared taskflow-test-helpers.ts to prevent drift between the tool and taskflow test suites.

Key changes:

  • lobster-runner.ts: runtime loading is memoized, token/approve are validated for the resume action, and the package-root resolver uses upward package.json traversal instead of fixed path offsets
  • lobster-tool.ts: parseResumeFlowParams now throws early if token or approve is missing in managed TaskFlow resume mode
  • taskflow-test-helpers.ts: new shared file consolidating the createFakeTaskFlow Vitest mock
  • Minor issues: the createLimitedSink error message uses "maxStdoutBytes" even for the stderr sink, flowExpectedRevision is typed as Type.Number() in the schema but validated as integer at runtime, and the timeout test relies on real wall-clock timing

Confidence Score: 4/5

PR is safe to merge; all new validation and memoization logic is correct and well-tested.

The core correctness changes — managed resume validation, runtime memoization, and the shared test helper extraction — are properly implemented and covered by new tests. The identified issues are cosmetic or schema-alignment concerns (misleading error message, Type.Number vs Type.Integer, real-clock timeout test, package.json name validation) that do not affect the guarded behavior introduced by this PR.

extensions/lobster/src/lobster-runner.ts (resolveInstalledLobsterRoot package name validation, createLimitedSink error message), extensions/lobster/src/lobster-tool.ts (flowExpectedRevision schema type)

Comments Outside Diff (4)

  1. extensions/lobster/src/lobster-runner.ts, line 189 (link)

    P2 Misleading error message for stderr sink

    The error always says maxStdoutBytes even when the overflowing sink is stderr (label === "stderr"), making it harder for callers to diagnose which stream was exhausted.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: extensions/lobster/src/lobster-runner.ts
    Line: 189
    
    Comment:
    **Misleading error message for stderr sink**
    
    The error always says `maxStdoutBytes` even when the overflowing sink is stderr (`label === "stderr"`), making it harder for callers to diagnose which stream was exhausted.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
  2. extensions/lobster/src/lobster-tool.ts, line 266-270 (link)

    P2 as cast is safe today but couples parseResumeFlowParams validation to runnerParams building implicitly

    The cast works correctly because parseResumeFlowParams validates that params.token and params.approve are present before returning a non-null result, and runnerParams is built from the same params source at lines 218–227. However, TypeScript cannot verify this invariant structurally — the correctness relies on the ordering dependency between these two blocks.

    If the runnerParams-building logic is ever decoupled from parseResumeFlowParams (e.g., moved into a factory or reordered), the cast would silently pass even with missing fields. Consider returning token and approve from ManagedFlowResumeParams and using those values to build the narrowed runnerParams, so TypeScript enforces the constraint structurally rather than through a cast.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: extensions/lobster/src/lobster-tool.ts
    Line: 266-270
    
    Comment:
    **`as` cast is safe today but couples `parseResumeFlowParams` validation to `runnerParams` building implicitly**
    
    The cast works correctly because `parseResumeFlowParams` validates that `params.token` and `params.approve` are present before returning a non-null result, and `runnerParams` is built from the same `params` source at lines 218–227. However, TypeScript cannot verify this invariant structurally — the correctness relies on the ordering dependency between these two blocks.
    
    If the `runnerParams`-building logic is ever decoupled from `parseResumeFlowParams` (e.g., moved into a factory or reordered), the cast would silently pass even with missing fields. Consider returning `token` and `approve` from `ManagedFlowResumeParams` and using those values to build the narrowed `runnerParams`, so TypeScript enforces the constraint structurally rather than through a cast.
    
    How can I resolve this? If you propose a fix, please make it concise.
  3. extensions/lobster/src/lobster-tool.ts, line 196 (link)

    P2 Schema type for flowExpectedRevision does not match the runtime integer check

    The schema declares Type.Number() (which permits floats like 1.5), but readOptionalNumber enforces Number.isInteger at runtime. A provider that validates the schema before sending could pass a float, receiving an opaque runtime error rather than a schema-level rejection. Aligning the schema to Type.Integer() (available in @sinclair/typebox) surfaces the constraint to providers at the schema boundary.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: extensions/lobster/src/lobster-tool.ts
    Line: 196
    
    Comment:
    **Schema type for `flowExpectedRevision` does not match the runtime integer check**
    
    The schema declares `Type.Number()` (which permits floats like `1.5`), but `readOptionalNumber` enforces `Number.isInteger` at runtime. A provider that validates the schema before sending could pass a float, receiving an opaque runtime error rather than a schema-level rejection. Aligning the schema to `Type.Integer()` (available in `@sinclair/typebox`) surfaces the constraint to providers at the schema boundary.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
  4. extensions/lobster/src/lobster-runner.test.ts, line 295-325 (link)

    P2 Timeout test depends on real wall-clock timing and may flake under CI load

    The test uses a 200 ms timeoutMs against a fake runtime that deliberately delays 500 ms. In heavily loaded CI environments the event loop can lag enough that the timing boundaries blur, causing intermittent failures. Using vi.useFakeTimers() with vi.advanceTimersByTimeAsync() would make this test deterministic regardless of host load and align with the repo's test performance guardrails.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: extensions/lobster/src/lobster-runner.test.ts
    Line: 295-325
    
    Comment:
    **Timeout test depends on real wall-clock timing and may flake under CI load**
    
    The test uses a 200 ms `timeoutMs` against a fake runtime that deliberately delays 500 ms. In heavily loaded CI environments the event loop can lag enough that the timing boundaries blur, causing intermittent failures. Using `vi.useFakeTimers()` with `vi.advanceTimersByTimeAsync()` would make this test deterministic regardless of host load and align with the repo's test performance guardrails.
    
    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/lobster/src/lobster-runner.ts
Line: 189

Comment:
**Misleading error message for stderr sink**

The error always says `maxStdoutBytes` even when the overflowing sink is stderr (`label === "stderr"`), making it harder for callers to diagnose which stream was exhausted.

```suggestion
      callback(new Error(`lobster ${label} output limit exceeded`));
```

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

---

This is a comment left during a code review.
Path: extensions/lobster/src/lobster-runner.ts
Line: 598-614

Comment:
**Package root resolver does not validate the found `package.json` belongs to `@clawdbot/lobster`**

`resolveInstalledLobsterRoot` walks upward from the resolved Lobster entry file and stops at the first `package.json` it encounters. In unusual layouts (symlinked `node_modules`, custom workspace hoisting, or monorepo overrides), the first `package.json` found could belong to a parent scope, causing incorrect module paths to be used downstream in `loadEmbeddedToolRuntimeFromPackage`.

Adding a name check after reading the file would make this robust against edge-case misresolves:

```ts
const { readFileSync } = await import("node:fs");
// inside the loop, after existsSync:
const pkg = JSON.parse(readFileSync(packageJsonPath, "utf8")) as { name?: string };
if (pkg.name === "@clawdbot/lobster") {
  return currentDir;
}
// otherwise continue walking upward
```

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

---

This is a comment left during a code review.
Path: extensions/lobster/src/lobster-tool.ts
Line: 266-270

Comment:
**`as` cast is safe today but couples `parseResumeFlowParams` validation to `runnerParams` building implicitly**

The cast works correctly because `parseResumeFlowParams` validates that `params.token` and `params.approve` are present before returning a non-null result, and `runnerParams` is built from the same `params` source at lines 218–227. However, TypeScript cannot verify this invariant structurally — the correctness relies on the ordering dependency between these two blocks.

If the `runnerParams`-building logic is ever decoupled from `parseResumeFlowParams` (e.g., moved into a factory or reordered), the cast would silently pass even with missing fields. Consider returning `token` and `approve` from `ManagedFlowResumeParams` and using those values to build the narrowed `runnerParams`, so TypeScript enforces the constraint structurally rather than through a cast.

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

---

This is a comment left during a code review.
Path: extensions/lobster/src/lobster-tool.ts
Line: 196

Comment:
**Schema type for `flowExpectedRevision` does not match the runtime integer check**

The schema declares `Type.Number()` (which permits floats like `1.5`), but `readOptionalNumber` enforces `Number.isInteger` at runtime. A provider that validates the schema before sending could pass a float, receiving an opaque runtime error rather than a schema-level rejection. Aligning the schema to `Type.Integer()` (available in `@sinclair/typebox`) surfaces the constraint to providers at the schema boundary.

```suggestion
      flowExpectedRevision: Type.Optional(Type.Integer()),
```

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

---

This is a comment left during a code review.
Path: extensions/lobster/src/lobster-runner.test.ts
Line: 295-325

Comment:
**Timeout test depends on real wall-clock timing and may flake under CI load**

The test uses a 200 ms `timeoutMs` against a fake runtime that deliberately delays 500 ms. In heavily loaded CI environments the event loop can lag enough that the timing boundaries blur, causing intermittent failures. Using `vi.useFakeTimers()` with `vi.advanceTimersByTimeAsync()` would make this test deterministic regardless of host load and align with the repo's test performance guardrails.

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

Reviews (1): Last reviewed commit: "Lobster: harden embedded runtime integra..." | Re-trigger Greptile

Comment on lines 598 to 614
function resolveInstalledLobsterRoot() {
const require = createRequire(import.meta.url);
const sdkEntry = require.resolve("@clawdbot/lobster");
return path.resolve(path.dirname(sdkEntry), "../../..");
let currentDir = path.dirname(sdkEntry);

while (true) {
const packageJsonPath = path.join(currentDir, "package.json");
if (existsSync(packageJsonPath)) {
return currentDir;
}
const parentDir = path.dirname(currentDir);
if (parentDir === currentDir) {
throw new Error("Unable to resolve the installed @clawdbot/lobster package root");
}
currentDir = parentDir;
}
}

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.

P2 Package root resolver does not validate the found package.json belongs to @clawdbot/lobster

resolveInstalledLobsterRoot walks upward from the resolved Lobster entry file and stops at the first package.json it encounters. In unusual layouts (symlinked node_modules, custom workspace hoisting, or monorepo overrides), the first package.json found could belong to a parent scope, causing incorrect module paths to be used downstream in loadEmbeddedToolRuntimeFromPackage.

Adding a name check after reading the file would make this robust against edge-case misresolves:

const { readFileSync } = await import("node:fs");
// inside the loop, after existsSync:
const pkg = JSON.parse(readFileSync(packageJsonPath, "utf8")) as { name?: string };
if (pkg.name === "@clawdbot/lobster") {
  return currentDir;
}
// otherwise continue walking upward
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/lobster/src/lobster-runner.ts
Line: 598-614

Comment:
**Package root resolver does not validate the found `package.json` belongs to `@clawdbot/lobster`**

`resolveInstalledLobsterRoot` walks upward from the resolved Lobster entry file and stops at the first `package.json` it encounters. In unusual layouts (symlinked `node_modules`, custom workspace hoisting, or monorepo overrides), the first `package.json` found could belong to a parent scope, causing incorrect module paths to be used downstream in `loadEmbeddedToolRuntimeFromPackage`.

Adding a name check after reading the file would make this robust against edge-case misresolves:

```ts
const { readFileSync } = await import("node:fs");
// inside the loop, after existsSync:
const pkg = JSON.parse(readFileSync(packageJsonPath, "utf8")) as { name?: string };
if (pkg.name === "@clawdbot/lobster") {
  return currentDir;
}
// otherwise continue walking upward
```

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

@mbelinky mbelinky force-pushed the pr/lobster-greptile-harden branch from f71eb74 to df02ffd Compare April 6, 2026 00:27
@mbelinky mbelinky mentioned this pull request Apr 6, 2026
25 tasks
@mbelinky mbelinky force-pushed the pr/lobster-greptile-harden branch from df02ffd to 9b9f58d Compare April 6, 2026 01:38

@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: 9b9f58db86

ℹ️ About Codex in GitHub

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

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

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

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

Comment thread CHANGELOG.md Outdated
- Providers/CLI: remove bundled CLI text-provider backends and the `agents.defaults.cliBackends` surface, while keeping ACP harness sessions and Gemini media understanding on the native bundled providers.
- Matrix/exec approvals: clarify unavailable-approval replies so Matrix no longer claims chat approvals are unsupported when native exec approvals are merely unconfigured. (#61424) Thanks @gumadeiras.
- Docs/IRC: replace public IRC hostname examples with `irc.example.com` and recommend private servers for bot coordination while listing common public networks for intentional use.
<<<<<<< HEAD

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Remove unresolved merge marker from changelog

The new <<<<<<< HEAD line is a merge-conflict artifact, not content, and it will leak into rendered release notes/changelog output as broken text. This can also break any tooling that expects clean Markdown changelog entries, so the marker should be removed before landing.

Useful? React with 👍 / 👎.

@mbelinky mbelinky force-pushed the pr/lobster-greptile-harden branch from 362e14c to a6f4830 Compare April 6, 2026 01:50
@mbelinky mbelinky merged commit b167df7 into main Apr 6, 2026
9 checks passed
@mbelinky mbelinky deleted the pr/lobster-greptile-harden branch April 6, 2026 01:52
@mbelinky

mbelinky commented Apr 6, 2026

Copy link
Copy Markdown
Contributor Author

Merged via squash.

Thanks @mbelinky!

Syysean pushed a commit to Syysean/openclaw that referenced this pull request Apr 6, 2026
Merged via squash.

Prepared head SHA: a6f4830
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
jjjojoj pushed a commit to jjjojoj/openclaw-jjjojoj that referenced this pull request Apr 6, 2026
Merged via squash.

Prepared head SHA: a6f4830
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
jjjojoj pushed a commit to jjjojoj/openclaw-jjjojoj that referenced this pull request Apr 6, 2026
Merged via squash.

Prepared head SHA: a6f4830
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
justuseapen added a commit to justuseapen/else-core that referenced this pull request Apr 6, 2026
* 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

* test(scripts): share temp dir helpers

* test(scripts): reuse temp dir helpers in runtime tests

* test(scripts): reuse temp dir helpers in repo fixtures

* test(scripts): add async temp dir helper

* fix: restore main ci type checks

* test(root): reuse temp repo helper in clawhub release tests

* test(root): clean up pre-commit temp repos

* fix(matrix): pass deviceId through health probe to prevent storage-meta overwrite (openclaw#61317) (openclaw#61581)

Merged via squash.

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

* test(root): share temp dir helper across root tests

* test(root): reuse temp dir helper in scoped vitest config

* test(root): reuse temp dir helper in launcher e2e

* test(tooling): reuse temp dir helpers in script tests

* test(unit): reuse temp dir helper in install-sh version tests

* test: reset telegram dispatch mocks between cases

* test(plugins): reuse tracked temp helpers in runtime staging tests

* test(plugins): reuse tracked temp helpers in path resolution tests

* test(plugins): reuse tracked temp helpers in fixture tests

* test(plugins): share async temp helpers in marketplace tests

* test(plugins): reuse tracked temp helpers in loader fixture tests

* test(plugins): share suite temp root helper in install path tests

* test(plugins): reuse suite temp root helper in install fixture tests

* test(plugins): reuse tracked temp helpers in package contract tests

* test(plugins): reuse suite temp helper in bundle contract test

* test(infra): reuse shared temp dir helpers in small file tests

* test(infra): reuse temp dir helper in utility file tests

* test(infra): reuse temp dir helper in run-node tests

* test(infra): reuse temp dir helpers in install source tests

* test(infra): reuse temp dir helper in install path safety tests

* perf(test): split reply command coverage

* perf(test): trim subagent command imports

* test: remove legacy commands monolith

* test(infra): reuse temp dir helper in node path tests

* test(infra): reuse temp dir helper in state and watch tests

* test(infra): reuse temp dir helper in sentinel and provider tests

* test(infra): share temp dir cleanup in git metadata tests

* test(infra): share tracked temp dirs in apns tests

* test(infra): reuse temp dir helper in fs safety tests

* test(infra): reuse temp dir helper in update status tests

* test(infra): share sync temp dir helper in approval tests

* test(infra): share suite temp root tracker in infra tests

* test(infra): reuse suite temp root tracker in update tests

* test(infra): reuse suite temp root tracker in provider auth tests

* test(infra): reuse suite temp root tracker in install tests

* test(infra): reuse suite temp root tracker in startup checks

* test(infra): reuse temp dir helper in global update tests

* test(infra): reuse temp dir helper in clawhub tests

* test(core): reuse shared temp dir helpers in utils tests

* test(infra): reuse temp dir helper in node pairing tests

* test(infra): reuse suite temp root tracker in device pairing tests

* test(core): reuse shared temp dir helper in logger tests

* test(e2e): reuse suite temp root tracker in docker setup tests

* test(infra): reuse suite temp root tracker in session cost tests

* test(config): reuse temp dir helper in config surface tests

* test(config): reuse temp dir helper in disk budget tests

* test(config): share session test fixture helper

* test(config): reuse suite temp root tracker in session key normalization tests

* test(config): reuse suite temp root tracker in store pruning integration tests

* test(config): reuse shared temp dir helpers in sessions tests

* test(config): reuse shared temp dir helper in store read tests

* perf(test): split subagent command coverage

* perf(test): trim secrets runtime coverage

* perf(test): split extra params resolver coverage

* fix(anthropic): restore OAuth guard in service-tier stream wrappers (openclaw#60356)

Merged via squash.

Prepared head SHA: 7d58bef
Co-authored-by: openperf <80630709+openperf@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman

* perf(test): split extra params wrapper coverage

* perf(secrets): trim runtime import walls

* perf(test): split security audit coverage

* refactor: dedupe plugin and outbound helpers

* refactor: share gateway auth and approval helpers

* refactor: share command config resolution

* refactor: consolidate status reporting helpers

* fix: resolve upstream sync conflicts (branding, firecrawl, lockfile)

Resolve 7 merge conflicts from sync/upstream-2026-04-06 (v2026.4.5):
- pnpm-lock.yaml: keep our platform-channel + upstream's qa-channel/qa-lab
- app-render.ts: add upstream session-key imports, deduplicate agentLogoUrl
- control-ui-bootstrap.ts: keep our branding (resolveUiBrand, title, agentId)
- control-ui-bootstrap.test.ts: keep our test expectations + upstream null checks
- schema.base.generated.ts: keep our Firecrawl + profile config entries
- schema.labels.ts: keep our Firecrawl + profile labels

Includes CVE-2026-33579 fix (callerScopes in /pair approve handler).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
Co-authored-by: Gustavo Madeira Santana <gumadeiras@gmail.com>
Co-authored-by: Mariano <132747814+mbelinky@users.noreply.github.com>
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
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: gumadeiras <5599352+gumadeiras@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: Vignesh <mailvgnsh@gmail.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: ToToKr <friendnt@g.skku.edu>
Co-authored-by: MoerAI <26067127+MoerAI@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
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: a6f4830
Co-authored-by: mbelinky <132747814+mbelinky@users.noreply.github.com>
Reviewed-by: @mbelinky
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
Merged via squash.

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

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

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

Labels

extensions: lobster Extension: lobster maintainer Maintainer-authored PR size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant