Thanks to visit codestin.com
Credit goes to github.com

Skip to content

TUI doesn't reload history/session state after gateway restart #1663

@hfyeomans

Description

@hfyeomans

Problem

When the gateway restarts, the TUI reconnects (exponential backoff works correctly), but doesn't reload conversation history if historyLoaded was already true before the disconnect. This means:

  1. Messages exchanged during the outage are lost from the TUI view
  2. Session state (agent, current session) may not restore properly
  3. Only manual actions like /status or /history can catch up

Steps to Reproduce

  1. Start TUI: clawdbot tui
  2. Load some history (messages appear in chat log)
  3. Restart gateway: clawdbot gateway restart (or via SIGUSR1)
  4. Wait for TUI to reconnect (shows "gateway reconnected")
  5. Messages sent during the outage are missing from TUI view

Expected Behavior

On onConnected, the TUI should:

  • Call loadHistory() to fetch messages since lastSeq (or reload full history)
  • Restore current agent/session state
  • Show a clearer reconnection state (progress, attempt count, etc.)

Current Behavior (from code review)

In tui.js (lines ~510-545):

  • client.onConnected() calls loadHistory() only if !historyLoaded
  • If historyLoaded === true, it just shows "gateway reconnected" without fetching missed events
  • This means any messages exchanged during disconnect are invisible in TUI

Suggested Fixes

Option 1: Always reload history after reconnect (simpler)

client.onConnected = () => {
    isConnected = true;
    setConnectionStatus("connected");
    void (async () => {
        await refreshAgents();
        updateHeader();
        // Always reload history on reconnect to catch missed events
        await loadHistory();
        setConnectionStatus("gateway reconnected", 4000);
        tui.requestRender();
        // ...
    })();
};

Option 2: Reload only if disconnect was detected (more efficient)

let wasDisconnected = false;

client.onDisconnected = (reason) => {
    isConnected = false;
    wasDisconnected = true;
    // ...
};

client.onConnected = () => {
    isConnected = true;
    setConnectionStatus("connected");
    void (async () => {
        await refreshAgents();
        updateHeader();
        // Reload history only if we had a disconnect
        if (wasDisconnected) {
            await loadHistory();
            wasDisconnected = false;
        }
        // ...
    })();
};

Option 3: Fetch events since last known sequence (most efficient)

  • Track lastSeq from incoming events
  • On reconnect, call chat.history with sinceSeq parameter if available
  • This would only fetch messages exchanged during the outage

Environment

  • Clawdbot version: 2026.1.22+ (from main)
  • OS: Linux (Raspberry Pi 5)
  • Terminal: (not specified)
  • Gateway: local mode (loopback)

Notes

  • Exponential backoff in GatewayClient works correctly (scheduleReconnect() in gateway/client.js)
  • The onGap handler exists for detecting event gaps, but is called during normal operation, not on reconnect
  • The protocol includes seq numbers for ordering; this could be leveraged for delta sync

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions