Class: Boxcars::Openai

Inherits:
Engine
  • Object
show all
Includes:
OpenAICompatibleChatHelpers, UnifiedObservability
Defined in:
lib/boxcars/engine/openai.rb

Overview

Engine that talks to OpenAI’s REST API.

Direct Known Subclasses

Cerebras, Google, Together

Constant Summary collapse

CHAT_MODEL_REGEX =
/(^gpt-4)|(-turbo\b)|(^o\d)|(gpt-3\.5-turbo)/
O_SERIES_REGEX =
/^o/
GPT5_MODEL_REGEX =
/\Agpt-[56].*/
DEFAULT_PARAMS =
{
  model: "gpt-4o-mini",
  temperature: 0.1,
  max_tokens: 4096
}.freeze
DEFAULT_NAME =
"OpenAI engine"
DEFAULT_DESCRIPTION =
"Useful when you need AI to answer questions. Ask targeted questions."

Instance Attribute Summary collapse

Attributes inherited from Engine

#batch_size, #user_id

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Engine

#add_usage_detail!, #aggregate_generate_usage!, #aggregate_token_usage_details!, #append_generate_choices!, #generate, #generate_one, #generation_info, #get_num_tokens, #normalize_generate_response, #process_generate_prompt!, #process_generate_response!, #run, #supports?, #usage_nested_token_value, #usage_token_value

Constructor Details

#initialize(name: DEFAULT_NAME, description: DEFAULT_DESCRIPTION, batch_size: 20, **kwargs) ⇒ Openai


Construction

Raises:



31
32
33
34
35
36
37
38
39
40
41
# File 'lib/boxcars/engine/openai.rb', line 31

def initialize(name: DEFAULT_NAME,
               description: DEFAULT_DESCRIPTION,
               batch_size: 20,
               **kwargs)
  raise ArgumentError, "unknown keyword: :prompts" if kwargs.key?(:prompts)

  user_id = kwargs.delete(:user_id)
  reject_deprecated_backend_kwargs!(kwargs)
  @open_ai_params = adjust_for_o_series!(DEFAULT_PARAMS.merge(kwargs))
  super(description:, name:, batch_size:, user_id:)
end

Instance Attribute Details

#open_ai_paramsObject (readonly)

Returns the value of attribute open_ai_params.



26
27
28
# File 'lib/boxcars/engine/openai.rb', line 26

def open_ai_params
  @open_ai_params
end

Class Method Details

.provider_client(openai_access_token: nil) ⇒ Object


Class helpers



100
101
102
103
104
105
106
# File 'lib/boxcars/engine/openai.rb', line 100

def self.provider_client(openai_access_token: nil)
  Boxcars::OpenAIClient.build(
    access_token: Boxcars.configuration.openai_access_token(openai_access_token:),
    organization_id: Boxcars.configuration.organization_id,
    log_errors: true
  )
end

Instance Method Details

#capabilitiesObject



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/boxcars/engine/openai.rb', line 85

def capabilities
  model_name = open_ai_params[:model].to_s
  tool_capable = chat_model?(model_name) || gpt5_model?(model_name)

  {
    tool_calling: tool_capable,
    structured_output_json_schema: tool_capable,
    native_json_object: chat_model?(model_name),
    responses_api: gpt5_model?(model_name)
  }
end

#client(prompt:, inputs: {}, openai_access_token: nil, **kwargs) ⇒ Object


Public API



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/boxcars/engine/openai.rb', line 46

def client(prompt:, inputs: {}, openai_access_token: nil, **kwargs)
  start_time       = Time.now
  response_data    = { response_obj: nil, parsed_json: nil,
                       success: false, error: nil, status_code: nil }
  reject_deprecated_backend_kwargs!(kwargs)
  current_params   = open_ai_params.merge(kwargs)
  is_chat_model    = chat_model?(current_params[:model])
  prompt_object    = prompt
  api_request      = build_api_request(prompt_object, inputs, current_params, chat: is_chat_model)

  begin
    raw_response = execute_api_call(
      self.class.provider_client(openai_access_token:),
      is_chat_model,
      api_request
    )
    process_response(raw_response, response_data)
  rescue StandardError => e
    handle_error(e, response_data)
  ensure
    track_openai_observability(
      {
        start_time:,
        prompt_object: prompt_object,
        inputs: inputs,
        api_request: api_request,
        current_params: current_params,
        is_chat_model: is_chat_model
      },
      response_data
    )
  end

  handle_call_outcome(response_data:)
end

#default_paramsObject

Expose the defaults so callers can introspect or dup/merge them



83
# File 'lib/boxcars/engine/openai.rb', line 83

def default_params = open_ai_params

#validate_response!(response, must_haves: %w[choices])) ⇒ Object

– Public helper ————————————————————- Some callers outside this class still invoke ‘validate_response!` directly. It simply raises if the JSON body contains an “error” payload.



111
112
113
114
115
116
117
# File 'lib/boxcars/engine/openai.rb', line 111

def validate_response!(response, must_haves: %w[choices])
  if response.is_a?(Hash) && response.key?("output")
    super(response, must_haves: %w[output])
  else
    super
  end
end