Last updated: Sep 1, 2025, 01:10 PM UTC

Fix Fake Token Counter Issue

Implementation Status: Not Started
Priority: Medium
Created: 2025-08-21
Last Updated: 2025-08-21
Owner: TBD

Problem Statement

The chat interface displays continuously increasing fake token counts when the backend is unavailable. Users see token counts growing indefinitely (e.g., "156,673 tokens" after 3304 seconds) which creates confusion and misleading UX.

Root Cause

In claudecodeui/src/components/SashaStatus.jsx:23, a fake token generator simulates token accumulation at 30-50 tokens/second whenever isLoading is true, regardless of actual backend status:

setFakeTokens(Math.floor(elapsed * (30 + Math.random() * 20)));

When the backend is unavailable:

  • No claude-complete or session-aborted events arrive to set isLoading to false
  • The timer runs indefinitely
  • Fake tokens accumulate continuously without bounds

Current Behavior

  • Good: Provides immediate visual feedback during normal processing
  • Good: Seamlessly transitions to real tokens when available
  • Bad: Continues indefinitely when backend fails
  • Bad: Shows unrealistic token counts (100k+)
  • Bad: No indication of connection problems

Proposed Solution

Implement simple backend failure detection to stop fake counting when the backend is definitively unavailable.

Key Principles

  1. Detect actual failures (not timeout-based assumptions)
  2. Preserve all state and user context
  3. Don't interrupt legitimate operations
  4. Provide honest status feedback

Detection Points

  • WebSocket disconnection events (onerror, onclose)
  • HTTP error responses (502/503/504)
  • Network error callbacks in request handlers
  • Connection state management failures

When Backend Failure Detected

  1. Stop fake token generation immediately
  2. Show subtle disconnection indicator
  3. Freeze current elapsed time display
  4. Preserve all conversation state
  5. Allow manual retry without losing context

Implementation Steps

1. Add Backend Connection State Management

File: claudecodeui/src/components/ChatInterface.jsx

const [backendConnected, setBackendConnected] = useState(true);

2. Update WebSocket/HTTP Error Handlers

Add connection state updates to existing error handlers:

// WebSocket handlers
ws.onerror = () => setBackendConnected(false);
ws.onclose = () => setBackendConnected(false);

// HTTP error handlers  
.catch(error => {
  if (error.response?.status >= 500) {
    setBackendConnected(false);
  }
  // existing error handling
});

3. Modify SashaStatus Component

File: claudecodeui/src/components/SashaStatus.jsx

function SashaStatus({ status, onAbort, isLoading, backendConnected }) {
  // Stop fake token generation if backend disconnected
  useEffect(() => {
    if (!isLoading || !backendConnected) {
      setElapsedTime(prev => prev); // freeze time
      setFakeTokens(prev => prev);   // freeze tokens
      return;
    }
    // existing timer logic
  }, [isLoading, backendConnected]);
}

4. Add Disconnection Indicator

Update status display to show connection state:

// In SashaStatus render
{!backendConnected && (
  <span className="text-red-500 text-sm">β€’ Disconnected</span>
)}

5. Update Component Props

Pass backendConnected state from ChatInterface to SashaStatus.

Testing Requirements

Test Scenarios

  1. Normal operation: Verify fake tokens still work during startup
  2. Backend failure: Simulate server down, verify counting stops
  3. Reconnection: Test state preservation when connection restored
  4. Long operations: Ensure legitimate 5+ minute operations aren't affected
  5. WebSocket failures: Test various disconnection scenarios
  6. HTTP failures: Test 502/503/504 error responses

Success Criteria

  • Fake tokens stop immediately on real backend failure
  • Connection indicator appears when backend unavailable
  • All conversation state preserved during disconnection
  • Normal operations unaffected by changes
  • Users can retry/reconnect manually
  • No false positives during legitimate long processing

Risk Assessment

Low Risk Changes

  • Adding connection state tracking
  • Modifying fake token generation logic
  • Adding disconnection indicator

Potential Issues

  • False disconnection detection: Ensure only real failures trigger state change
  • State synchronization: Backend reconnection should restore normal operation
  • UI/UX consistency: Disconnection indicator should be subtle, not alarming

Mitigation Strategies

  • Use only definitive failure signals (not timeouts)
  • Test with various network conditions
  • Implement gradual rollout if possible
  • Maintain backward compatibility

Files to Modify

  1. claudecodeui/src/components/ChatInterface.jsx - Connection state management
  2. claudecodeui/src/components/SashaStatus.jsx - Fake token logic and UI
  3. Any WebSocket/HTTP client code - Error handler updates

Success Metrics

  • Fake token counting stops within 1-2 seconds of backend failure
  • Zero false positive disconnection indicators during normal operation
  • User reports of confusion about endless token counting eliminated
  • No regression in legitimate long-running operation UX