From b7c5124081f8a0a2a179d5619ced3b269b5dd317 Mon Sep 17 00:00:00 2001 From: sol Date: Mon, 9 Mar 2026 15:26:14 +0000 Subject: [PATCH] fix: fast-idle session on openclaw.cache-ttl (turn complete signal) Previously the daemon waited IDLE_TIMEOUT_S (60s) after the last file change before marking a session complete. But the JSONL file is kept open by the gateway indefinitely, so file inactivity was never reliable. Fix: detect the 'openclaw.cache-ttl' custom record which the gateway emits after every completed assistant turn. When pendingToolCalls == 0, start a 3-second grace timer instead of the full 60s idle timeout. Result: live status clears within ~3 seconds of the agent's final reply instead of lingering for 60+ seconds (or indefinitely on active sessions). Fixes: session stays 'active' long after work is done --- src/status-watcher.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/status-watcher.js b/src/status-watcher.js index 2f953a3..8ed1732 100644 --- a/src/status-watcher.js +++ b/src/status-watcher.js @@ -379,6 +379,21 @@ class StatusWatcher extends EventEmitter { return; } + // OpenClaw cache-ttl custom record: reliable "turn complete" signal. + // Emitted after every assistant turn. Use it to fast-idle the session + // instead of waiting the full IDLE_TIMEOUT_S. + if (record.type === 'custom' && record.customType === 'openclaw.cache-ttl') { + if (state.pendingToolCalls === 0) { + // Turn is done — fast-idle: fire idle check after a short grace period (3s) + // to allow any trailing writes to flush before marking complete. + if (state.idleTimer) clearTimeout(state.idleTimer); + state.idleTimer = setTimeout(() => { + this._checkIdle(sessionKey); + }, 3000); + } + return; + } + // Legacy format fallback (for compatibility) var legacyType = record.type;