Module: Event::Broadcasting

Extended by:
ActiveSupport::Concern
Included in:
Event
Defined in:
app/models/concerns/event/broadcasting.rb

Overview

Broadcasts Event records to connected WebSocket clients via ActionCable. Follows the Turbo Streams pattern: events are broadcast on both create and update, with an action type so clients can distinguish append from replace operations.

Each broadcast includes the Event’s database ID, enabling clients to maintain an ID-indexed store for efficient in-place updates (e.g. when token counts arrive asynchronously from CountEventTokensJob).

When a new event pushes old events out of the LLM’s context window, the broadcast includes ‘evicted_event_ids` so clients can remove phantom messages that the agent no longer knows about.

Examples:

Create broadcast payload

{
  "type" => "user_message", "content" => "hello", ...,
  "id" => 42, "action" => "create",
  "rendered" => { "basic" => { "role" => "user", "content" => "hello" } }
}

Broadcast with viewport evictions

{
  "type" => "agent_message", "content" => "...", ...,
  "id" => 99, "action" => "create",
  "evicted_event_ids" => [101, 102, 103]
}

Update broadcast payload (e.g. token count arrives)

{
  "type" => "user_message", "content" => "hello", ...,
  "id" => 42, "action" => "update",
  "rendered" => { "debug" => { "role" => "user", "content" => "hello", "tokens" => 15 } }
}

Constant Summary collapse

ACTION_CREATE =
"create"
ACTION_UPDATE =
"update"

Instance Method Summary collapse

Instance Method Details

#broadcast_now!Object

Broadcasts this event immediately, bypassing after_create_commit. Used inside a wrapping transaction where after_create_commit is deferred until the outer transaction commits. Gives clients optimistic UI — the event appears right away and is removed via bounce if the transaction rolls back.

Sets a flag so the deferred after_create_commit callback skips the duplicate broadcast after the transaction commits.



55
56
57
58
# File 'app/models/concerns/event/broadcasting.rb', line 55

def broadcast_now!
  @already_broadcast = true
  broadcast_event(action: ACTION_CREATE)
end