Class: Mistri::Providers::Gemini::Assembler
- Inherits:
-
Object
- Object
- Mistri::Providers::Gemini::Assembler
- Defined in:
- lib/mistri/providers/gemini/assembler.rb
Overview
Folds streamGenerateContent records into the event union. Each record carries delta parts: plain text extends a text block, thought parts a thinking block, and a functionCall arrives whole, so its three events emit back to back. A kind switch closes the open block.
Thought signatures ride on individual parts and are captured onto the block they arrived with, verbatim, for replay.
Defined Under Namespace
Classes: Builder
Instance Method Summary collapse
- #abort ⇒ Object
- #fail_stream(reason) ⇒ Object
- #feed(record) ⇒ Object
-
#finish(&emit) ⇒ Object
A stream that ended without a finishReason was truncated, not cancelled: fail it so the loop can treat it as retryable.
-
#initialize(model:) ⇒ Assembler
constructor
A new instance of Assembler.
- #message ⇒ Object
Constructor Details
Instance Method Details
#abort ⇒ Object
49 50 51 52 |
# File 'lib/mistri/providers/gemini/assembler.rb', line 49 def abort(&) close_current terminal(StopReason::ABORTED, "aborted", &) end |
#fail_stream(reason) ⇒ Object
54 55 56 57 58 59 60 61 62 |
# File 'lib/mistri/providers/gemini/assembler.rb', line 54 def fail_stream(reason, &) close_current text = case reason when ProviderError then "#{reason.class}: #{reason.describe}" when Exception then "#{reason.class}: #{reason.}" else reason.to_s end terminal(StopReason::ERROR, text, error: ErrorData.for(reason), &) end |
#feed(record) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/mistri/providers/gemini/assembler.rb', line 24 def feed(record, &) if (error = record["error"]) @error = ProviderError.new(error["message"] || "provider error", status: error["code"]) return end candidate = record.dig("candidates", 0) || {} Array(candidate.dig("content", "parts")).each { |part| fold_part(part, &) } @finish_reason = candidate["finishReason"] if candidate["finishReason"] @usage = parse_usage(record["usageMetadata"]) if record["usageMetadata"] end |
#finish(&emit) ⇒ Object
A stream that ended without a finishReason was truncated, not cancelled: fail it so the loop can treat it as retryable.
39 40 41 42 43 44 45 46 47 |
# File 'lib/mistri/providers/gemini/assembler.rb', line 39 def finish(&emit) return fail_stream(@error, &emit) if @error return fail_stream("stream ended without a finish reason", &emit) unless @finish_reason close_current(&emit) @message = assemble(stop_reason: stop_reason) emit&.call(Event.new(type: :done, reason: @message.stop_reason, message: @message)) @message end |
#message ⇒ Object
64 |
# File 'lib/mistri/providers/gemini/assembler.rb', line 64 def = @message ||= finish |