Class: Anthropic::Helpers::Sessions::EventAccumulator
- Inherits:
-
Object
- Object
- Anthropic::Helpers::Sessions::EventAccumulator
- Defined in:
- lib/anthropic/helpers/sessions/event_accumulator.rb,
sig/anthropic/helpers/sessions/event_accumulator.rbs
Overview
Accumulates session stream events into agent.message snapshots.
event_delta previews are lossy and best-effort; the buffered final
agent.message event is canonical and replaces whatever the preview
accumulated. A span.model_request_end event closes all open previews
(the producing model request ended without emitting the buffered
event), discarding their partial snapshots.
Defined Under Namespace
Classes: AccumulationError
Instance Attribute Summary collapse
-
#agent_messages ⇒ Hash{String => Anthropic::Models::Beta::Sessions::BetaManagedAgentsAgentMessageEvent}
readonly
Snapshots keyed by event id, including those still accumulating.
Instance Method Summary collapse
-
#accumulate(event) ⇒ Anthropic::Models::Beta::Sessions::BetaManagedAgentsStreamSessionEvents
Folds one stream event into the accumulated state and returns the event unchanged.
-
#agent_message_text(event_id) ⇒ String?
The concatenated text of the accumulated
agent.messagewith the given event id, ornilwhen the id is unknown. -
#initialize ⇒ EventAccumulator
constructor
A new instance of EventAccumulator.
- #on_event_delta(event) ⇒ void
- #on_event_start(event) ⇒ void
-
#wrap(enum) ⇒ Enumerator<Anthropic::Models::Beta::Sessions::BetaManagedAgentsStreamSessionEvents>
Returns an Enumerator that lazily folds each event from
enumthrough #accumulate and yields it unchanged.
Constructor Details
#initialize ⇒ EventAccumulator
Returns a new instance of EventAccumulator.
34 35 36 |
# File 'lib/anthropic/helpers/sessions/event_accumulator.rb', line 34 def initialize @agent_messages = {} end |
Instance Attribute Details
#agent_messages ⇒ Hash{String => Anthropic::Models::Beta::Sessions::BetaManagedAgentsAgentMessageEvent} (readonly)
Snapshots keyed by event id, including those still accumulating.
While a preview is open the snapshot is partial and its
processed_at is unset; once the buffered final agent.message
arrives it is the canonical event.
32 33 34 |
# File 'lib/anthropic/helpers/sessions/event_accumulator.rb', line 32 def @agent_messages end |
Instance Method Details
#accumulate(event) ⇒ Anthropic::Models::Beta::Sessions::BetaManagedAgentsStreamSessionEvents
Folds one stream event into the accumulated state and returns the event unchanged.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/anthropic/helpers/sessions/event_accumulator.rb', line 48 def accumulate(event) case event.type in :event_start on_event_start(event) in :event_delta on_event_delta(event) in :"agent.message" @agent_messages[event.id] = event in :"span.model_request_end" # The model request ended without buffering the previewed events # (an error or interrupt mid-stream); discard the open previews. # Canonical events (`processed_at` set) survive. @agent_messages.delete_if { |_, | .processed_at.nil? } else # Other event types carry no `agent.message` content. end event end |
#agent_message_text(event_id) ⇒ String?
The concatenated text of the accumulated agent.message with the
given event id, or nil when the id is unknown.
87 88 89 |
# File 'lib/anthropic/helpers/sessions/event_accumulator.rb', line 87 def (event_id) @agent_messages[event_id]&.content&.filter_map { _1.text if _1.type == :text }&.join end |
#on_event_delta(event) ⇒ void
This method returns an undefined value.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
# File 'lib/anthropic/helpers/sessions/event_accumulator.rb', line 107 def on_event_delta(event) snapshot = @agent_messages[event.event_id] if snapshot.nil? raise AccumulationError.new( "event_delta for #{event.event_id} received before its event_start" ) end # The final event is canonical; drop deltas that straggle in after it. return unless snapshot.processed_at.nil? index = event.delta.index || 0 fragment = event.delta.content content = snapshot.content # Indices arrive in order — the first delta at a new index opens the # slot. A gap means deltas arrived out of order or were mis-routed. unless (0..content.length).cover?(index) raise AccumulationError.new( "event_delta index #{index} is beyond the end of content (length #{content.length})" ) end existing = content[index] if existing.nil? # Copy the fragment so later appends never mutate the wire event. block = Anthropic::Beta::Sessions::BetaManagedAgentsTextBlock.new( type: fragment.type, text: fragment.text ) snapshot.content = content + [block] elsif fragment.type == :text && existing.type == :text existing.text += fragment.text else # Unrecognised fragment type: no-op; the canonical event fills the gap. end end |
#on_event_start(event) ⇒ void
This method returns an undefined value.
93 94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/anthropic/helpers/sessions/event_accumulator.rb', line 93 def on_event_start(event) # `agent.thinking` previews are start-only today; deltas may come later. return unless event.event.type == :"agent.message" id = event.event.id # `processed_at` is left unset: that is what marks the snapshot as an # open preview until the buffered final event reconciles it. @agent_messages[id] = Anthropic::Beta::Sessions::BetaManagedAgentsAgentMessageEvent.new( id: id, type: :"agent.message", content: [] ) end |
#wrap(enum) ⇒ Enumerator<Anthropic::Models::Beta::Sessions::BetaManagedAgentsStreamSessionEvents>
Returns an Enumerator that lazily folds each event from enum
through #accumulate and yields it unchanged. The enumerator is
fused: it can be consumed once, and re-iterating yields nothing
rather than folding deltas a second time.
75 76 77 78 79 |
# File 'lib/anthropic/helpers/sessions/event_accumulator.rb', line 75 def wrap(enum) Anthropic::Internal::Util.chain_fused(enum) do |yielder| enum.each { yielder << accumulate(_1) } end end |