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
Constant Summary collapse
- VERDICTS =
Finish reasons that are the provider's verdict on the content itself: a retry of the same input meets the same filter, and a harness that re-rolls against a policy verdict is machinery for evading it, so these fail fast.
%w[SAFETY RECITATION LANGUAGE BLOCKLIST PROHIBITED_CONTENT SPII IMAGE_SAFETY IMAGE_PROHIBITED_CONTENT IMAGE_RECITATION].freeze
- INPUT_ERRORS =
Missing replay state accuses the request rather than the generated content, but retrying the same history is equally deterministic.
%w[MISSING_THOUGHT_SIGNATURE].freeze
- FUMBLES =
The model fumbled its own output (an invalid or runaway tool call, a missing image), or the API stopped for a reason it cannot name (OTHER is documented as "Unknown reason"). The input stands accused of nothing, so these error retryably; a regeneration usually lands.
%w[MALFORMED_FUNCTION_CALL UNEXPECTED_TOOL_CALL TOO_MANY_TOOL_CALLS NO_IMAGE OTHER IMAGE_OTHER MALFORMED_RESPONSE FINISH_REASON_UNSPECIFIED].freeze
Instance Method Summary collapse
- #abort ⇒ Object
- #fail_stream(reason, usage_known: false) ⇒ 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:, catalog_pricing: true, service_tier: nil) ⇒ Assembler
constructor
A new instance of Assembler.
- #message ⇒ Object
- #start(&emit) ⇒ Object
Constructor Details
#initialize(model:, catalog_pricing: true, service_tier: nil) ⇒ Assembler
Returns a new instance of Assembler.
17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/mistri/providers/gemini/assembler.rb', line 17 def initialize(model:, catalog_pricing: true, service_tier: nil) @model = model @catalog_pricing = catalog_pricing @service_tier = service_tier @pricing_at = Time.now @blocks = [] @current = nil @usage = Usage.new @finish_reason = nil @terminal = false end |
Instance Method Details
#abort ⇒ Object
106 107 108 109 110 |
# File 'lib/mistri/providers/gemini/assembler.rb', line 106 def abort(&) close_current(&) invalidate_cost terminal(StopReason::ABORTED, "aborted", &) end |
#fail_stream(reason, usage_known: false) ⇒ Object
112 113 114 115 116 117 118 119 120 121 |
# File 'lib/mistri/providers/gemini/assembler.rb', line 112 def fail_stream(reason, usage_known: false, &) close_current(&) invalidate_cost unless usage_known 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
50 51 52 53 54 55 |
# File 'lib/mistri/providers/gemini/assembler.rb', line 50 def feed(record, &) return after_terminal(record, &) if @terminal return record_error(record["error"]) if record["error"] fold_record(record, &) 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.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/mistri/providers/gemini/assembler.rb', line 85 def finish(&emit) return fail_stream(@error, &emit) if @error if (refused = blocked) return fail_stream(refused, usage_known: @usage_authoritative, &emit) end return fail_stream("stream ended without a finish reason", &emit) unless @finish_reason if @blocks.any?(ToolCall) && !%w[STOP MAX_TOKENS].include?(@finish_reason) invalidate_tool_calls reason = ProviderError.new("generation ended before its tool calls were confirmed: " \ "#{@finish_reason}") return fail_stream(reason, usage_known: @usage_authoritative, &emit) end close_current(&emit) invalidate_cost unless @usage_authoritative @message = assemble(stop_reason: stop_reason) emit&.call(Event.new(type: :done, reason: @message.stop_reason, message: @message)) @message end |
#message ⇒ Object
123 |
# File 'lib/mistri/providers/gemini/assembler.rb', line 123 def = @message ||= finish |