Class: RubyLLM::Providers::OpenAIResponses

Inherits:
OpenAI show all
Defined in:
lib/ruby_llm/providers/openai_responses.rb

Overview

OpenAI Responses API provider. Uses v1/responses endpoint instead of v1/chat/completions. Inherits from OpenAI and overrides only what differs.

Constant Summary

Constants included from RubyLLM::Providers::OpenAI::Tools

RubyLLM::Providers::OpenAI::Tools::EMPTY_PARAMETERS_SCHEMA

Instance Attribute Summary collapse

Attributes inherited from RubyLLM::Provider

#config, #connection

Instance Method Summary collapse

Methods inherited from OpenAI

#api_base, capabilities, configuration_requirements, #headers, #maybe_normalize_temperature

Methods included from RubyLLM::Providers::OpenAI::Transcription

encode_speaker_references, parse_transcription_response, render_transcription_payload, response_format_for, supports_chunking_strategy?, transcription_url

Methods included from RubyLLM::Providers::OpenAI::Media

format_audio, format_content, format_image, format_pdf, format_text, format_text_file

Methods included from RubyLLM::Providers::OpenAI::Images

images_url, parse_image_response, render_image_payload

Methods included from RubyLLM::Providers::OpenAI::Tools

format_tool_calls, param_schema, parameters_schema_for, parse_tool_call_arguments, parse_tool_calls, schema_from_parameters, tool_for

Methods included from RubyLLM::Providers::OpenAI::Streaming

build_chunk, parse_streaming_error, stream_url

Methods included from RubyLLM::Providers::OpenAI::Moderation

moderation_url, parse_moderation_response, render_moderation_payload

Methods included from RubyLLM::Providers::OpenAI::Models

models_url, parse_list_models_response

Methods included from RubyLLM::Providers::OpenAI::Embeddings

embedding_url, parse_embedding_response, render_embedding_payload

Methods included from RubyLLM::Providers::OpenAI::Chat

format_messages, format_role, parse_completion_response, render_payload

Methods inherited from RubyLLM::Provider

#api_base, #capabilities, capabilities, #configuration_requirements, configuration_requirements, configured?, #configured?, configured_providers, configured_remote_providers, #embed, for, #format_messages, #format_tool_calls, #headers, #list_models, #local?, local?, local_providers, #moderate, name, #name, #paint, #parse_error, #parse_tool_calls, providers, register, remote?, #remote?, remote_providers, resolve, slug, #slug, #transcribe

Methods included from Streaming

handle_stream, stream_response

Constructor Details

#initialize(config, responses_session = nil, responses_config = {}) ⇒ OpenAIResponses

Returns a new instance of OpenAIResponses.



11
12
13
14
15
16
17
18
19
20
21
# File 'lib/ruby_llm/providers/openai_responses.rb', line 11

def initialize(config, responses_session = nil, responses_config = {})
  @responses_session = responses_session || ResponsesSession.new
  @responses_config = {
    stateful: false,
    store: true,
    truncation: :disabled,
    include: []
  }.merge(responses_config)

  super(config)
end

Instance Attribute Details

#responses_config ⇒ Object (readonly)

Returns the value of attribute responses_config.



9
10
11
# File 'lib/ruby_llm/providers/openai_responses.rb', line 9

def responses_config
  @responses_config
end

#responses_session ⇒ Object (readonly)

Returns the value of attribute responses_session.



9
10
11
# File 'lib/ruby_llm/providers/openai_responses.rb', line 9

def responses_session
  @responses_session
end

Instance Method Details

#build_chunk(data) ⇒ Object

Override build_chunk for Responses API streaming events



96
97
98
99
100
101
102
# File 'lib/ruby_llm/providers/openai_responses.rb', line 96

def build_chunk(data)
  if responses_api_event?(data)
    build_responses_chunk(data)
  else
    super
  end
end

#complete(messages, tools:, temperature:, model:, params: {}, headers: {}, schema: nil, &block) ⇒ Object

Override complete to handle response ID failures



29
30
31
32
33
34
35
36
# File 'lib/ruby_llm/providers/openai_responses.rb', line 29

def complete(messages, tools:, temperature:, model:, params: {}, headers: {}, schema: nil, &block) # rubocop:disable Metrics/ParameterLists
  super
rescue BadRequestError => e
  raise unless response_id_not_found_error?(e)

  handle_response_id_failure
  retry
end

#completion_url ⇒ Object

Override endpoint URL - no conditionals needed



24
25
26
# File 'lib/ruby_llm/providers/openai_responses.rb', line 24

def completion_url
  'responses'
end

#parse_completion_response(response) ⇒ Object

Override parse_completion_response for Responses API format



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/ruby_llm/providers/openai_responses.rb', line 55

def parse_completion_response(response)
  data = response.body
  return if data.nil? || !data.is_a?(Hash) || data.empty?

  # Check status first to handle failed responses appropriately
  case data['status']
  when 'completed'
    parse_completed_response(data, response)
  when 'failed'
    raise ResponseFailedError.new(response, data.dig('error', 'message') || 'Response failed')
  when 'in_progress', 'queued'
    raise ResponseInProgressError.new(response, "Response still processing: #{data['id']}")
  when 'cancelled'
    raise ResponseCancelledError.new(response, "Response was cancelled: #{data['id']}")
  when 'incomplete'
    parse_incomplete_response(data, response)
  else
    # For responses without status, check for error
    raise Error.new(response, data.dig('error', 'message')) if data.dig('error', 'message')

    parse_completed_response(data, response)
  end
end

#render_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) ⇒ Object

Override render_payload for Responses API format



39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/ruby_llm/providers/openai_responses.rb', line 39

def render_payload(messages, tools:, temperature:, model:, stream: false, schema: nil) # rubocop:disable Metrics/ParameterLists
  system_msgs, other_msgs = partition_messages(messages)

  payload = build_base_payload(model, stream)
  add_instructions(payload, system_msgs)
  add_input(payload, other_msgs)
  add_temperature(payload, temperature)
  add_tools(payload, tools)
  add_schema(payload, schema)
  add_optional_parameters(payload)
  add_stream_options(payload, stream)

  payload
end

#tool_for(tool) ⇒ Object

Override tool_for for flat format (not nested under 'function')



80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/ruby_llm/providers/openai_responses.rb', line 80

def tool_for(tool)
  parameters_schema = parameters_schema_for(tool)

  definition = {
    type: 'function',
    name: tool.name,
    description: tool.description,
    parameters: parameters_schema
  }

  return definition if tool.provider_params.empty?

  RubyLLM::Utils.deep_merge(definition, tool.provider_params)
end