When no nodes are paired, file-transfer tools now fail before node alias resolution with an actionable message instead of generic unknown-node retries. The paired-node schema wording also steers agents away from local/host/gateway/auto guesses.\n\nFixes #91482.
Rewrite recognized docs-root markdown links in Control UI renderers to https://docs.openclaw.ai while preserving Control UI routes, base-mounted resources, and plugin viewer URLs.
Fixes#89465.
Adds /context detail diagnostics for active transcript compactability so prompt/cache usage is not mistaken for compactable conversation history.
Fixes#91150. Supersedes #91158.
Co-authored-by: Rain <94058511+Pluviobyte@users.noreply.github.com>
drainNextQueueItem captured items[0], awaited the run, then shift()-ed
index 0 assuming it still held the item it ran. Concurrent inbound
messages mutate the same shared items array, and at or over cap
applyQueueDropPolicy splices items off the front, so a burst arriving
while item[0] is in flight can shift a different, still-undelivered
survivor into index 0. shift() then deletes that survivor: it is never
run and is not counted in the overflow summary, so the agent silently
ignores a message it should have answered.
Remove the item that actually ran by identity via a new
removeQueuedItemsByRef helper, and apply the same reference-based
removal to the collect path in drain.ts, which had the same positional
splice(0, groupItems.length) assumption after an awaited group run.
Exec approval followups were dispatched by sessionKey only. When /new or
/reset rotates the sessionId under that key while an approval is pending,
the resolved followup landed in the new session, surfacing stale approval
output (or 'Exec denied' / continuation text) in a fresh conversation.
Capture the session UUID active when the approval is requested and drop the
followup once the key has been rebound to a different sessionId:
- agent-run followups: carry the expected id on the agent request and drop it
at the gateway as an early preflight, before the handler touches the rebound
session (session-store write, chat/agent run + active-run registration,
dedupe, accepted ack) — not just before model dispatch. Covers elevated and
non-elevated.
- denied / direct fallback followups: resolve the key's current sessionId from
the session store and drop before the channel send.
Fixes#59349.
ensureLoaded cast persisted rows through `as unknown as CronJob[]` and then
back to `Record<string, unknown>` per item, which mislabeled unvalidated data
as CronJob. Treat the rows as raw records at the store boundary and apply a
single trusted CronJob cast only after getInvalidPersistedCronJobReason passes,
preserving the normalize/validate/quarantine flow. Drops two redundant casts
and two lines with no behavior change.
Fixes#91314
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit e9e494c7fe)
ensureCollections() never rebound a managed collection after its root
path changed (e.g. an agent workspace repoint): listCollectionsBestEffort()
read `qmd collection list`, whose output carries no filesystem path, so
listed.path was always undefined and shouldRebindCollection took its
defensive branch and skipped the rebind. The collection stayed pinned to
the stale root and recall kept resolving the old location.
Enrich the listed collections with their path via `qmd collection show`
so path-change detection works and the rebind fires.
Closes#91251
(cherry picked from commit 4a225011e9)
Detect text accumulated before tool_use blocks in the Claude CLI
streaming parser and emit it as commentary via a new onCommentaryText
callback. This enables the same commentary progress display that the
Codex backend already provides through preamble item events.
- Add onCommentaryText optional callback to createCliJsonlStreamingParser
- Flush accumulated assistantText as commentary when content_block_start
with tool_use type is encountered
- Track last flushed position to avoid duplicate emissions on consecutive
tool_use blocks without intervening text
- Wire the callback in both execute.ts (regular CLI spawn + live session)
and claude-live-session.ts, emitting AgentItemEventData with
kind=preamble and progressText
- Add 3 test cases covering: text before tool_use, empty text before
tool_use, and consecutive tool_use dedup
Commentary lines carry noCompact so the progress-draft renderer does not compact
them like tool lines — assistant prose renders in full, spilling to a new message
at the channel limit rather than truncating mid-sentence.
Post-tool empty OpenAI-compatible stop turns no longer qualify as intentional silence, so replay-safe attempts use the existing empty-response retry and unsafe attempts surface the existing incomplete-turn error instead of disappearing.
Fixes#91394
Normalize Codex dynamic tool progress result payloads to TUI-compatible content arrays after sanitization, while stripping protocol-only fields from the emitted event.
Includes regression coverage for sanitized dynamic tool text/image progress output.
Thanks @bdjben.
Gateway/background sync now repairs missing memory index metadata with the existing full reindex path when the configured embedding provider is available, while preserving dirty/paused state instead of downgrading semantic chunks when embeddings are unavailable.
Fixes#90338
Make lexical FTS/LIKE search ignore embedding model identity so exact keyword recall survives provider/model changes. Vector search remains model-scoped, and refreshed or stale FTS rows are cleaned by path/source with live-chunk filtering to prevent old orphan rows from surfacing.
Fixes#48300