mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-11 19:26:07 +00:00
* fix: recover terminal session status on visible inbound turns (#86827) When a group chat session enters a terminal status (failed/timeout/killed), subsequent visible inbound messages now automatically recover the session by clearing stale lifecycle fields while preserving the session ID and transcript continuity. Changes: - session.ts: detect terminal status on visible turns and clear status/ startedAt/endedAt/runtimeMs/abortedLastRun without rotating sessionId - dispatch-from-config.ts: force-clear stale active reply operations for terminal sessions and retry admission once - agent.ts: mirror terminal recovery in the agent API dispatch path - kernel.ts: add zero-count visible dispatch warning diagnostic - types.ts: add 'warning' to ChannelTurnLogEvent event union * fix: guard terminal recovery from concurrent force-clear race When two visible messages arrive against the same terminal session snapshot, the second turn could force-fail the first turn's freshly admitted recovery operation, dropping the very message the recovery path exists to save. Add a terminalRecovery flag on ReplyOperation that is set after a recovery turn clears the proven stale leftover and admits its own operation. The force-clear branch now skips operations marked as in-flight terminal recoveries, letting concurrent turns fall through to normal busy/wait handling instead. Add a two-turn regression test that gates the first recovery turn open, races a second visible turn against the same terminal snapshot, and asserts neither turn's operation is incorrectly killed. Also fix missing FinalizedMsgContext import in kernel.ts. * fix: avoid return value in Promise executor to satisfy lint * fix: gate terminal force-clear to visible reply turns A heartbeat/control turn can pass the early active-run short-circuit, reach the terminal force-clear branch, and abort an in-flight visible recovery operation that a concurrent visible turn just admitted (before that op is marked terminalRecovery). Gate the force-clear to visible reply turns so non-visible turns fall through to normal busy/skip handling instead of killing the recovery they are meant to protect. Adds a focused regression test exercising a heartbeat turn that reaches the force-clear branch against a terminal session snapshot with an active recovery operation present; it must leave that operation intact and skip. * fix: verify session identity before terminal force-clear * fix: mark clean no-stale terminal recovery to survive concurrent visible turn The same-session terminal-recovery race could still drop a reply when two visible turns raced the same failed snapshot. The terminalRecovery marker was set only on the post-force-clear re-admission path, never on the clean no-stale admission path. So when the first turn admitted cleanly (no stale op to clear), its recovery op stayed terminalRecovery=false and a second concurrent visible turn force-cleared it, dropping the first reply (#86827). Consolidate marking to the single owned-admission choke point that both the clean no-stale admission and the re-admission-after-force-clear flow through. Genuine stale leftovers from the original failed run never pass through this admission, so they stay unmarked and remain force-clearable. Add a no-stale regression twin to the existing stale-race test. * fix: suppress zero-count visible-dispatch warning for observed-delivery turns maybeWarnZeroCountVisibleDispatch re-implemented a partial visibility check that omitted observedReplyDelivery, so visible turns delivered via the observed-delivery path (queuedFinal=false, zero counts, observedReplyDelivery=true) falsely tripped the silent-drop sentinel and emitted a bogus zero-count-visible-dispatch warning/event. Use the canonical hasVisibleChannelTurnDispatch helper for the warning suppression so all non-count delivery paths (observedReplyDelivery, fallback, summary, queuedFinal) are honored. Add regression tests covering the observed-delivery case (no warning) and a genuinely empty visible dispatch (still warns). * test: read persisted session store in failed-group recovery test --------- Co-authored-by: 忻役 <xinyi@mininglamp.com>