Class: TUI::MessageStore

Inherits:
Object
  • Object
show all
Defined in:
lib/tui/message_store.rb

Overview

Thread-safe in-memory store for chat entries displayed in the TUI. Replaces Events::Subscribers::MessageCollector in the WebSocket-based TUI, with no dependency on Rails or the Events module.

Accepts Action Cable event payloads and stores typed entries:

  • ‘:rendered, data:, event_type:` for events with structured decorator output

  • ‘:message, role:, content:` for user/agent messages (fallback)

  • ‘:tool_counter, calls:, responses:` for tool activity

Structured data takes priority when available. Events with nil rendered content fall back to existing behavior: tool events aggregate into counters, messages store role and content.

Tool counters aggregate per agent turn: a new counter starts when a tool_call arrives after a message entry. Consecutive tool events increment the same counter until the next message breaks the chain.

Constant Summary collapse

MESSAGE_TYPES =
%w[user_message agent_message].freeze
ROLE_MAP =
{
  "user_message" => "user",
  "agent_message" => "assistant"
}.freeze

Instance Method Summary collapse

Constructor Details

#initializeMessageStore

Returns a new instance of MessageStore.



28
29
30
31
# File 'lib/tui/message_store.rb', line 28

def initialize
  @entries = []
  @mutex = Mutex.new
end

Instance Method Details

#clearvoid

This method returns an undefined value.

Removes all entries. Called on view mode change and session switch to prepare for re-decorated viewport events from the server.



63
64
65
# File 'lib/tui/message_store.rb', line 63

def clear
  @mutex.synchronize { @entries = [] }
end

#messagesArray<Hash>

Returns thread-safe copy of stored entries.

Returns:

  • (Array<Hash>)

    thread-safe copy of stored entries



34
35
36
# File 'lib/tui/message_store.rb', line 34

def messages
  @mutex.synchronize { @entries.dup }
end

#process_event(event_data) ⇒ Boolean

Processes a raw event payload from the WebSocket channel. Uses structured decorator data when available; falls back to role/content extraction for messages and tool counter aggregation.

Parameters:

  • event_data (Hash)

    Action Cable event payload with “type”, “content”, and optionally “rendered” (hash of mode => lines)

Returns:

  • (Boolean)

    true if the event type was recognized and handled



45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/tui/message_store.rb', line 45

def process_event(event_data)
  rendered = extract_rendered(event_data)

  if rendered
    record_rendered(rendered, event_type: event_data["type"])
  else
    case event_data["type"]
    when "tool_call" then record_tool_call
    when "tool_response" then record_tool_response
    when *MESSAGE_TYPES then record_message(event_data)
    else false
    end
  end
end