Module: SwarmSDK::V3::EventStream

Defined in:
lib/swarm_sdk/v3/event_stream.rb

Overview

EventStream provides fiber-local event emission for V3 agents

Thread-safe and fiber-safe event system using Fiber storage. Each fiber gets its own emitter instance, preventing cross-fiber contamination.

Two emitter slots are available:

  • **Global emitter** (via ‘emitter=`): For logging/monitoring across all operations

  • **Block emitter** (via ‘block_emitter=`): For per-call event handling in `ask()` blocks

Examples:

Emit an event

EventStream.emit(type: "agent_start", agent: :backend, model: "claude-sonnet-4")

Subscribe to events globally

EventStream.emitter = ->(event) { puts event.inspect }
agent.ask("Hello")
EventStream.reset!

Receive events via block (set internally by Agent#ask)

agent.ask("Hello") do |event|
  case event[:type]
  when "content_chunk"
    print event[:content]
  end
end

Constant Summary collapse

FIBER_KEY =
:v3_event_stream_emitter
BLOCK_KEY =
:v3_event_stream_block_emitter

Class Method Summary collapse

Class Method Details

.block_emitter#call?

Get the current block emitter

Returns:

  • (#call, nil)

    Current block emitter or nil



92
93
94
# File 'lib/swarm_sdk/v3/event_stream.rb', line 92

def block_emitter
  Fiber[BLOCK_KEY]
end

.block_emitter=(callable) ⇒ void

This method returns an undefined value.

Set the block emitter for the current fiber

Used internally by Agent#ask to wire the user’s block to receive events. Not typically called directly by SDK users.

Parameters:

  • callable (#call, nil)

    Object responding to call(Hash), or nil to clear



85
86
87
# File 'lib/swarm_sdk/v3/event_stream.rb', line 85

def block_emitter=(callable)
  Fiber[BLOCK_KEY] = callable
end

.emit(**data) ⇒ void

This method returns an undefined value.

Emit a structured event

Adds timestamp and forwards to both the global emitter and block emitter. No-op if no emitters are configured.

Examples:

EventStream.emit(
  type: "tool_call",
  agent: :backend,
  tool: "Read",
  arguments: { file_path: "src/main.rb" },
)

Parameters:

  • data (Hash)

    Event data (type, agent, and event-specific fields)



49
50
51
52
53
54
55
56
57
58
# File 'lib/swarm_sdk/v3/event_stream.rb', line 49

def emit(**data)
  global = Fiber[FIBER_KEY]
  block = Fiber[BLOCK_KEY]
  return if global.nil? && block.nil?

  entry = data.merge(timestamp: Time.now.utc.iso8601(6)).compact

  call_emitter(global, entry)
  call_emitter(block, entry)
end

.emitter#call?

Get the current global emitter

Returns:

  • (#call, nil)

    Current emitter or nil



74
75
76
# File 'lib/swarm_sdk/v3/event_stream.rb', line 74

def emitter
  Fiber[FIBER_KEY]
end

.emitter=(callable) ⇒ void

This method returns an undefined value.

Set the global emitter for the current fiber

Use this for logging, monitoring, and analytics that should receive all events regardless of where they originate.

Parameters:

  • callable (#call)

    Object responding to call(Hash)



67
68
69
# File 'lib/swarm_sdk/v3/event_stream.rb', line 67

def emitter=(callable)
  Fiber[FIBER_KEY] = callable
end

.enabled?Boolean

Check if any emitter is configured

Returns:

  • (Boolean)


107
108
109
# File 'lib/swarm_sdk/v3/event_stream.rb', line 107

def enabled?
  !Fiber[FIBER_KEY].nil? || !Fiber[BLOCK_KEY].nil?
end

.reset!void

This method returns an undefined value.

Reset both emitters for the current fiber



99
100
101
102
# File 'lib/swarm_sdk/v3/event_stream.rb', line 99

def reset!
  Fiber[FIBER_KEY] = nil
  Fiber[BLOCK_KEY] = nil
end