Class: Xeno::Channels::Slack::Streamer

Inherits:
Object
  • Object
show all
Defined in:
lib/xeno/channels/slack.rb

Overview

Post-then-edit delivery for ONE streaming model reply. The first content delta posts the thread message; later deltas edit it at most once per EDIT_INTERVAL; finish writes the durable final text. Rate limits defer the next edit (Retry-After); any hard failure turns streaming off for this reply — the completion post is the fallback, and the durable truth is rows either way.

Constant Summary collapse

EDIT_INTERVAL =

seconds — comfortably under chat.update's tier

1.0

Instance Method Summary collapse

Constructor Details

#initialize(slack, channel:, thread_ts:) ⇒ Streamer

Returns a new instance of Streamer.



131
132
133
134
135
136
137
138
139
140
# File 'lib/xeno/channels/slack.rb', line 131

def initialize(slack, channel:, thread_ts:)
  @slack = slack
  @channel = channel
  @thread_ts = thread_ts
  @buffer = +""
  @ts = nil
  @posted_text = nil
  @next_edit_at = 0.0
  @dead = false
end

Instance Method Details

#finish(final_text) ⇒ Object

Returns true when this streamer delivered the reply (the runner then skips the completion post); false hands delivery back.



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/xeno/channels/slack.rb', line 152

def finish(final_text)
  return false if @ts.nil?

  text = final_text.to_s
  return true if @posted_text == text

  wait = @next_edit_at - now
  sleep([ wait, 3.0 ].min) if wait.positive? # respect a pending rate-limit window
  @slack.api_post("chat.update", channel: @channel, ts: @ts, text: text)
  @posted_text = text
  true
rescue StandardError => e
  Rails.logger.warn("xeno: slack streaming final edit failed: #{e.class}: #{e.message}")
  false
end

#push(chunk) ⇒ Object



142
143
144
145
146
147
148
# File 'lib/xeno/channels/slack.rb', line 142

def push(chunk)
  content = chunk.respond_to?(:content) ? chunk.content : nil
  return if @dead || content.to_s.empty?

  @buffer << content
  @ts.nil? ? start_message : edit_message(@buffer.dup)
end