Class: RubyLLM::AiSdk::Stream

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_llm/ai_sdk/stream.rb

Overview

Writes one assistant turn of a Chat to an IO as AI SDK UI message stream events. Text and reasoning stream as they arrive, tool calls and their results follow each step, and tool calls parked on an approval end the turn with an approval request.

stream = RubyLLM::AiSdk::Stream.new(chat, response.stream)
stream.ask "Refund order 42"

A Stream only writes during its own turn, so several streams can be built on the same chat over its lifetime, one per request.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(chat, io) ⇒ Stream

Returns a new instance of Stream.



22
23
24
25
26
27
28
29
# File 'lib/ruby_llm/ai_sdk/stream.rb', line 22

def initialize(chat, io)
  @chat = chat
  @io = io
  @denied = []
  @step = false
  @active = false
  chat.after_message { |message| append(message) if @active }
end

Instance Attribute Details

#chat ⇒ Object (readonly)

The Chat this stream writes.



17
18
19
# File 'lib/ruby_llm/ai_sdk/stream.rb', line 17

def chat
  @chat
end

#io ⇒ Object (readonly)

The IO the events go to. Anything that responds to write.



20
21
22
# File 'lib/ruby_llm/ai_sdk/stream.rb', line 20

def io
  @io
end

Instance Method Details

#ask(text, **options) ⇒ Object

Asks text and streams the response. Accepts the same keyword arguments as Chat#ask. Returns the final Message.



46
47
48
# File 'lib/ruby_llm/ai_sdk/stream.rb', line 46

def ask(text, **options)
  turn { chat.ask(text, **options, &method(:receive)) }
end

#complete(message_id: nil) ⇒ Object

Continues a turn the chat already staged, such as one parked on an approval, and streams the response. Pass the id of the assistant message the client is showing as message_id so it continues that message instead of starting a new one. Returns the final Message.



54
55
56
# File 'lib/ruby_llm/ai_sdk/stream.rb', line 54

def complete(message_id: nil)
  turn(message_id) { chat.complete(&method(:receive)) }
end

#serve(request) ⇒ Object

Handles one useChat request end to end. Records the approval decisions when the request carries them and continues the parked turn, otherwise asks the last user message with its files attached. Returns the final Message.



35
36
37
38
39
40
41
42
# File 'lib/ruby_llm/ai_sdk/stream.rb', line 35

def serve(request)
  request = Request.parse(request) if request.is_a?(String)
  request = Request.new(request) if request.is_a?(Hash)
  return ask(request.text, with: request.files) if request.approvals.empty?

  request.approvals.each { |approval| decide(approval) }
  complete(message_id: request.message_id)
end