Class: RubyLLM::Providers::OpenAIResponses::Batch
- Inherits:
-
Object
- Object
- RubyLLM::Providers::OpenAIResponses::Batch
- Defined in:
- lib/ruby_llm/providers/openai_responses/batch.rb
Overview
High-level interface for OpenAI’s Batch API. Hides JSONL serialization, file upload, polling, and result parsing behind a clean Ruby API that mirrors RubyLLM::Chat.
Instance Attribute Summary collapse
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#requests ⇒ Object
readonly
Returns the value of attribute requests.
Instance Method Summary collapse
-
#add(input, id: nil, instructions: nil, temperature: nil, tools: nil, **extra) ⇒ self
Queue a request for inclusion in the batch.
-
#cancel! ⇒ self
Cancel the batch.
- #cancelled? ⇒ Boolean
- #completed? ⇒ Boolean
-
#completed_count ⇒ Integer?
Number of completed requests.
-
#create!(metadata: nil) ⇒ self
Build JSONL, upload the file, and create the batch.
-
#errors ⇒ Array<Hash>
Download and parse the error file.
- #expired? ⇒ Boolean
- #failed? ⇒ Boolean
-
#failed_count ⇒ Integer?
Number of failed requests.
- #in_progress? ⇒ Boolean
-
#initialize(model: nil, provider: :openai_responses, id: nil) ⇒ Batch
constructor
A new instance of Batch.
-
#refresh! ⇒ self
Fetch the latest batch status from the API.
-
#results ⇒ Hash<String, Message>
Download and parse the output file into a Hash of Messages.
-
#status ⇒ String?
Batch status.
-
#total_count ⇒ Integer?
Total number of requests.
-
#wait!(interval: 30, timeout: nil) {|Batch| ... } ⇒ self
Block until the batch reaches a terminal status.
Constructor Details
#initialize(model: nil, provider: :openai_responses, id: nil) ⇒ Batch
Returns a new instance of Batch.
25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 25 def initialize(model: nil, provider: :openai_responses, id: nil) @model = model @provider = resolve_provider(provider) @requests = [] @request_counter = 0 @data = {} return unless id @id = id refresh! end |
Instance Attribute Details
#id ⇒ Object (readonly)
Returns the value of attribute id.
20 21 22 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 20 def id @id end |
#requests ⇒ Object (readonly)
Returns the value of attribute requests.
20 21 22 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 20 def requests @requests end |
Instance Method Details
#add(input, id: nil, instructions: nil, temperature: nil, tools: nil, **extra) ⇒ self
Queue a request for inclusion in the batch.
45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 45 def add(input, id: nil, instructions: nil, temperature: nil, tools: nil, **extra) # rubocop:disable Metrics/ParameterLists custom_id = id || "request_#{@request_counter}" @request_counter += 1 body = { model: @model, input: Batches.normalize_input(input) } body[:instructions] = instructions if instructions body[:temperature] = temperature if temperature body[:tools] = tools if tools body.merge!(extra) unless extra.empty? @requests << { custom_id: custom_id, body: body } self end |
#cancel! ⇒ self
Cancel the batch.
183 184 185 186 187 188 189 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 183 def cancel! raise Error.new(nil, 'Batch not yet created') unless @id response = @provider.instance_variable_get(:@connection).post(Batches.cancel_batch_url(@id), {}) @data = response.body self end |
#cancelled? ⇒ Boolean
133 134 135 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 133 def cancelled? status == Batches::CANCELLED end |
#completed? ⇒ Boolean
113 114 115 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 113 def completed? status == Batches::COMPLETED end |
#completed_count ⇒ Integer?
Returns Number of completed requests.
98 99 100 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 98 def completed_count @data.dig('request_counts', 'completed') end |
#create!(metadata: nil) ⇒ self
Build JSONL, upload the file, and create the batch.
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 62 def create!(metadata: nil) raise Error.new(nil, 'No requests added') if @requests.empty? raise Error.new(nil, 'Batch already created') if @id jsonl = Batches.build_jsonl(@requests) file_id = upload_file(jsonl) payload = { input_file_id: file_id, endpoint: '/v1/responses', completion_window: '24h' } payload[:metadata] = if response = @provider.instance_variable_get(:@connection).post(Batches.batches_url, payload) @data = response.body @id = @data['id'] self end |
#errors ⇒ Array<Hash>
Download and parse the error file.
173 174 175 176 177 178 179 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 173 def errors error_file_id = @data['error_file_id'] return [] unless error_file_id jsonl = fetch_file_content(error_file_id) Batches.parse_errors(jsonl) end |
#expired? ⇒ Boolean
128 129 130 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 128 def expired? status == Batches::EXPIRED end |
#failed? ⇒ Boolean
123 124 125 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 123 def failed? status == Batches::FAILED end |
#failed_count ⇒ Integer?
Returns Number of failed requests.
108 109 110 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 108 def failed_count @data.dig('request_counts', 'failed') end |
#in_progress? ⇒ Boolean
118 119 120 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 118 def in_progress? Batches.pending?(status) end |
#refresh! ⇒ self
Fetch the latest batch status from the API.
84 85 86 87 88 89 90 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 84 def refresh! raise Error.new(nil, 'Batch not yet created') unless @id response = @provider.instance_variable_get(:@connection).get(Batches.batch_url(@id)) @data = response.body self end |
#results ⇒ Hash<String, Message>
Download and parse the output file into a Hash of Messages.
163 164 165 166 167 168 169 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 163 def results output_file_id = @data['output_file_id'] raise Error.new(nil, 'No output file available yet') unless output_file_id jsonl = fetch_file_content(output_file_id) Batches.(jsonl) end |
#status ⇒ String?
Returns Batch status.
93 94 95 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 93 def status @data['status'] end |
#total_count ⇒ Integer?
Returns Total number of requests.
103 104 105 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 103 def total_count @data.dig('request_counts', 'total') end |
#wait!(interval: 30, timeout: nil) {|Batch| ... } ⇒ self
Block until the batch reaches a terminal status.
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
# File 'lib/ruby_llm/providers/openai_responses/batch.rb', line 142 def wait!(interval: 30, timeout: nil) start_time = Time.now loop do refresh! yield self if block_given? break if Batches.terminal?(status) if timeout && (Time.now - start_time) > timeout raise Error.new(nil, "Batch polling timeout after #{timeout} seconds") end sleep interval end self end |