Module: SwarmSDK::Agent::ChatHelpers::EventEmitter

Included in:
SwarmSDK::Agent::Chat
Defined in:
lib/swarm_sdk/agent/chat_helpers/event_emitter.rb

Overview

Minimal event emitter that mirrors RubyLLM::Chat's callback pattern

Provides multi-subscriber support for events like tool_call, tool_result, new_message, end_message. This is thread-safe and supports unsubscription.

Defined Under Namespace

Classes: Subscription

Instance Method Summary collapse

Instance Method Details

#callback_count(event = nil) ⇒ Integer, Hash

Returns the number of callbacks registered for the specified event.

Parameters:

  • (defaults to: nil)

    The event to count callbacks for, or nil for all events

Returns:

  • Count for specific event, or hash of counts for all events



160
161
162
163
164
165
166
167
168
# File 'lib/swarm_sdk/agent/chat_helpers/event_emitter.rb', line 160

def callback_count(event = nil)
  @callback_monitor.synchronize do
    if event
      @callbacks[event]&.size || 0
    else
      @callbacks.transform_values(&:size)
    end
  end
end

#clear_callbacks(event = nil) ⇒ self

Clears all callbacks for the specified event, or all events if none specified.

Parameters:

  • (defaults to: nil)

    The event to clear callbacks for, or nil for all events

Returns:

  • for chaining



145
146
147
148
149
150
151
152
153
154
# File 'lib/swarm_sdk/agent/chat_helpers/event_emitter.rb', line 145

def clear_callbacks(event = nil)
  @callback_monitor.synchronize do
    if event
      @callbacks[event]&.clear
    else
      @callbacks.each_value(&:clear)
    end
  end
  self
end

#initialize_event_emittervoid

This method returns an undefined value.

Initialize the event emitter system

Sets up @callbacks hash and @callback_monitor for thread safety. Must be called in Chat#initialize.



57
58
59
60
61
62
63
64
65
# File 'lib/swarm_sdk/agent/chat_helpers/event_emitter.rb', line 57

def initialize_event_emitter
  @callbacks = {
    new_message: [],
    end_message: [],
    tool_call: [],
    tool_result: [],
  }
  @callback_monitor = Monitor.new
end

#on_end_message {|Message| ... } ⇒ self

Registers a callback for when a message is complete. Multiple callbacks can be registered and all will fire in registration order.

Yields:

  • (Message)

    Block called with the completed message

Returns:

  • for chaining



116
117
118
119
# File 'lib/swarm_sdk/agent/chat_helpers/event_emitter.rb', line 116

def on_end_message(&block)
  subscribe(:end_message, &block)
  self
end

#on_new_message { ... } ⇒ self

Registers a callback for when a new message starts being generated. Multiple callbacks can be registered and all will fire in registration order.

Yields:

  • Block called when a new message starts

Returns:

  • for chaining



106
107
108
109
# File 'lib/swarm_sdk/agent/chat_helpers/event_emitter.rb', line 106

def on_new_message(&block)
  subscribe(:new_message, &block)
  self
end

#on_tool_call {|ToolCall| ... } ⇒ self

Registers a callback for when a tool is called. Multiple callbacks can be registered and all will fire in registration order.

Yields:

  • (ToolCall)

    Block called with the tool call object

Returns:

  • for chaining



126
127
128
129
# File 'lib/swarm_sdk/agent/chat_helpers/event_emitter.rb', line 126

def on_tool_call(&block)
  subscribe(:tool_call, &block)
  self
end

#on_tool_result {|Object| ... } ⇒ self

Registers a callback for when a tool returns a result. Multiple callbacks can be registered and all will fire in registration order.

Yields:

  • (Object)

    Block called with the tool result

Returns:

  • for chaining



136
137
138
139
# File 'lib/swarm_sdk/agent/chat_helpers/event_emitter.rb', line 136

def on_tool_result(&block)
  subscribe(:tool_result, &block)
  self
end

#once(event, tag: nil) { ... } ⇒ Subscription

Subscribes to an event that automatically unsubscribes after firing once.

Parameters:

  • The event to subscribe to

  • (defaults to: nil)

    Optional tag for debugging/identification

Yields:

  • The block to call when the event fires (once)

Returns:

  • An object that can be used to unsubscribe before it fires



92
93
94
95
96
97
98
99
# File 'lib/swarm_sdk/agent/chat_helpers/event_emitter.rb', line 92

def once(event, tag: nil, &block)
  subscription = nil
  wrapper = lambda do |*args|
    subscription&.unsubscribe
    block.call(*args)
  end
  subscription = subscribe(event, tag: tag, &wrapper)
end

#subscribe(event, tag: nil) { ... } ⇒ Subscription

Subscribes to an event with the given block. Returns a Subscription that can be used to unsubscribe.

Parameters:

  • The event to subscribe to

  • (defaults to: nil)

    Optional tag for debugging/identification

Yields:

  • The block to call when the event fires

Returns:

  • An object that can be used to unsubscribe

Raises:

  • if event is not recognized



75
76
77
78
79
80
81
82
83
84
# File 'lib/swarm_sdk/agent/chat_helpers/event_emitter.rb', line 75

def subscribe(event, tag: nil, &block)
  @callback_monitor.synchronize do
    unless @callbacks.key?(event)
      raise ArgumentError, "Unknown event: #{event}. Valid events: #{@callbacks.keys.join(", ")}"
    end

    @callbacks[event] << block
    Subscription.new(@callbacks[event], block, monitor: @callback_monitor, tag: tag)
  end
end