The forward substring check in isMessagingToolDuplicateNormalized treated any
reply containing a prior message-tool send as a duplicate, with no length
floor. A short interim update sent via the message tool then suppressed the
entire final reply that restated it, and the user never received the answer.
The reverse direction already carried a 0.5 length ratio floor. Apply the same
floor to the forward direction so a reply is only deduped when the prior send
covers at least half of it.
* fix(agents): apply image context to current turn
* fix(agents): align runtime context with prompt order
* fix(agents): make turn context position independent
* fix(agents): bind internal context to the active user turn
Keep current-turn runtime context position-independent while preserving the shared privacy notice, runtime events, prompt-cache placement, and historical preface sanitization. Consolidate header detection in its existing owner and retain the original real turn-boundary regression.
Fixes#110672
Co-authored-by: chernoff-code <221717140+chernoff-code@users.noreply.github.com>
---------
Co-authored-by: chernoff-code <221717140+chernoff-code@users.noreply.github.com>
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Keep shared endpoint routing signal-aware while preserving explicit signal-specific URLs exactly. Cover the resolver through mocked constructors and real OTLP/HTTP trace, metric, and log exporters.
Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Why: managed discussion reconciliation must tolerate current ClickClack response shapes without persisting undefined plugin state or stale display titles.
Co-authored-by: Chisel <chisel@psiclawops.dev>
Prevent stale top-level buttons arguments from silently sending text-only Telegram messages. Point model guidance and docs to typed presentation actions, and reject retired input before delivery.
* fix(system-agent): a failed reset leaves the old conversation in context
`openclaw.chat` with `reset: true` discards the live session and disposes its
engine before verifying inference and building the welcome. The durable reset
marker was only written after both of those steps, so an inference outage during
a reset destroyed the session without recording the boundary. The next ordinary
session then seeded model context from the pre-reset transcript, because seeding
reads only the turns after the newest reset marker.
Record the boundary in a finally around the disposal, so it survives both a
rejected disposal and a replacement that fails to initialize, and drop the later
write. Disposal still runs first, so a failed marker write cannot leak the engine.
* fix(system-agent): persist resets before discarding live sessions
Persist the durable reset marker before deleting the live session so a failed SQLite write leaves the session, engine, and pending approval untouched. Preserve the original real-SQLite privacy-boundary regression coverage.
Co-authored-by: Masato Hoshino <g515hoshino@gmail.com>
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
…s in error
The 150 ms delta throttle in emitChatDelta withholds the most recent chunk
without scheduling it, leaving it in the run buffer for a later event to
deliver. emitChatTerminal exists to be that event: it flushes the buffer
before emitting the terminal frame.
On the error terminal it cannot, because the buffer is cleared at the top of
the branch, before finalizeLifecycleEvent runs. The flush then resolves empty
text and no-ops, so the withheld tail never reaches the chat channel, and a
terminal that classifies as a cancellation resolves its message to undefined.
The clear is redundant on the immediate branch: finalizeLifecycleEvent already
clears the buffer itself, after emitChatTerminal has flushed and resolved the
terminal message. Removing it there fixes both the missing delta and the
missing message. The deferred retry-grace branch still needs the clear so a
fallback attempt cannot merge onto the failed attempt's text, so flush before
clearing there, matching the pre-tool and pre-item flush sites in the same
function.
The end terminal was already correct, which is why this stayed invisible.
Co-authored-by: Tak Hoffman <781889+Takhoffman@users.noreply.github.com>