Dreaming's deep-phase promotion path appends to ~/.openclaw/workspace-<agent>/MEMORY.md
without a durable size budget. After weeks of use, the file grows past the bootstrap
injection cap (~12KB/file), at which point bootstrap silently truncates promoted memory
and (per the issue body) session writes can hit lock timeouts that wedge the gateway.
Adds a bounded compaction step in applyShortTermPromotions: before each write, drop the
OLDEST auto-promoted sections (date-ordered) until existing + new section fits within
memoryFileMaxChars (default 10,000 chars, safely below the 12KB bootstrap cap).
User-authored content is preserved unconditionally; only dreaming-owned sections are
eligible for compaction.
Verified:
- pnpm install --frozen-lockfile
- pnpm test extensions/memory-core/src/memory-budget.test.ts extensions/memory-core/src/short-term-promotion.test.ts
- pnpm exec oxfmt --check --threads=1 extensions/memory-core/src/memory-budget.ts extensions/memory-core/src/memory-budget.test.ts extensions/memory-core/src/short-term-promotion.ts extensions/memory-core/src/short-term-promotion.test.ts CHANGELOG.md
- pnpm check:changed
- pnpm tsgo:core
- pnpm tsgo:extensions
- pnpm tsgo:test:src
- git diff --check
- live driver: real applyShortTermPromotions across 5 sweeps with oversized seeded MEMORY.md — file stayed bounded, oldest sections compacted, user content preserved
Closes#73691
QQBot's gateway captured `ctx.cfg` once at startup and reused that
reference for every inbound, so peer-specific bindings added via the
CLI were ignored until the gateway restarted (the routing resolver
caches evaluated bindings keyed by the cfg object reference).
Add a small `ActiveCfgProvider` that reads `getRuntimeConfig()` from
the plugin SDK on every event and falls back to the startup snapshot
when the runtime registry is not populated, mirroring Telegram's
per-event lookup pattern. Wire it into `handleMessage` so both the
inbound pipeline and outbound dispatch run against the live config.
Fixes#69546.
Closes#80268
For Chrome MCP existing-session profiles, browser status previously
exposed only transport-handshake fields (cdpHttp, cdpReady) sourced
from isTransportAvailable(...). It did not surface whether a
page-level tool round-trip (list_pages, etc.) actually succeeds, so
operators and downstream tooling had no honest signal to distinguish
"transport handshake passed" from "page tools are usable".
This adds a pageReady field to BrowserStatus, derived from
profileCtx.isReachable(...) for chrome-mcp profiles (with a status-
bound 5s timeout) and mirroring cdpReady for managed CDP profiles
where the WS handshake already covers page-level reachability.
The status route opts the page probe into ephemeral mode so a passive
status call does not seed a persistent cached Chrome MCP session as a
side effect. listChromeMcpTabs reuses an existing cached attach
session if one already exists, otherwise opens a temporary session
that is closed immediately after the round-trip. The cached-session
path used by /tabs and other interactive routes is unchanged.
isReachable now threads the new ephemeral option (alongside timeoutMs)
into listChromeMcpTabs; existing callers in tabs.ts pass only
timeoutMs and continue to use the cached path.
The page probe is skipped when transport itself is down so status
latency does not regress on offline profiles.
Test changes:
- basic.existing-session.test.ts: the prior assertion that running:
true and cdpReady: true with isReachable: false is now flipped to
assert pageReady: false in that state, matching the new contract.
- New tests cover: probe-throws (treated as page-down), both-succeed
(pageReady: true), transport-down (probe skipped, pageReady: false),
and an ephemeral-mode regression that asserts the status probe
passes { ephemeral: true } so it cannot seed a cached session.