Class: LittleGhost::Providers::OpenAI

Inherits:
OpenAICompatible show all
Defined in:
lib/little_ghost/providers/openai.rb

Overview

OpenAI connects LittleGhost features to OpenAI models for generation and embeddings. Generation uses the Responses API by default and supports streaming, Tools, and structured results.

provider = LittleGhost::Providers::OpenAI.new(
api_key: ENV.fetch("OPENAI_API_KEY"),
model: ENV.fetch("OPENAI_MODEL")
)

Supply api: :chat_completions only when a model or integration requires the Chat Completions wire API.

Constant Summary collapse

DEFAULT_BASE_URL =

The OpenAI API endpoint used when base_url is omitted.

"https://api.openai.com/v1/"
DEFAULT_MAX_EMBEDDING_RESPONSE_BYTES =

:nodoc:

8 * 1024 * 1024

Constants inherited from OpenAICompatible

LittleGhost::Providers::OpenAICompatible::CONTEXT_OVERFLOW_MARKERS, LittleGhost::Providers::OpenAICompatible::INITIAL_RETRY_DELAY, LittleGhost::Providers::OpenAICompatible::MAX_RETRY_DELAY, LittleGhost::Providers::OpenAICompatible::TRANSIENT_STREAM_ERROR_TYPES

Instance Attribute Summary

Attributes inherited from OpenAICompatible

#api, #model

Instance Method Summary collapse

Methods inherited from OpenAICompatible

#capabilities, request_options, #stream

Methods inherited from Base

#capabilities, #prepare_request, request_options, #stream

Constructor Details

#initialize(base_url: DEFAULT_BASE_URL, max_embedding_response_bytes: DEFAULT_MAX_EMBEDDING_RESPONSE_BYTES, **arguments) ⇒ OpenAI

Uses the official OpenAI API base URL by default.

max_embedding_response_bytes bounds the response retained for one embedding batch. Remaining arguments configure the shared generation transport and retry behavior.

Raises:

  • (ArgumentError)


28
29
30
31
32
33
# File 'lib/little_ghost/providers/openai.rb', line 28

def initialize(base_url: DEFAULT_BASE_URL, max_embedding_response_bytes: DEFAULT_MAX_EMBEDDING_RESPONSE_BYTES, **arguments)
  @max_embedding_response_bytes = Integer(max_embedding_response_bytes)
  raise ArgumentError, "max_embedding_response_bytes must be positive" unless @max_embedding_response_bytes.positive?

  super(base_url:, **arguments)
end

Instance Method Details

#embed(request) ⇒ Object

Embeds one or more strings with the configured OpenAI model.

The optional :dimensions request setting selects a supported output size for models that accept it. The response preserves input order and raises ProtocolError when OpenAI returns an incomplete or invalid batch.



40
41
42
43
44
45
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
# File 'lib/little_ghost/providers/openai.rb', line 40

def embed(request)
  attempts = 0
  begin
    request.cancellation_token.raise_if_cancelled!
    payload = {
      model:,
      input: request.inputs,
      encoding_format: "float"
    }
    dimensions = request.settings[:dimensions]
    payload[:dimensions] = Integer(dimensions) if dimensions
    body = +""
    @transport.stream(
      path: "embeddings",
      headers: {"Authorization" => "Bearer #{@api_key}", "Content-Type" => "application/json"}.merge(@headers),
      body: JSON.generate(payload),
      cancellation_token: request.cancellation_token,
      deadline: request.deadline
    ) do |chunk|
      if body.bytesize + chunk.bytesize > @max_embedding_response_bytes
        raise ProtocolError, "OpenAI embedding response exceeded #{@max_embedding_response_bytes} bytes"
      end
      body << chunk
    end
    normalize_embedding_response(body, request.inputs.length, dimensions && Integer(dimensions))
  rescue HTTPError => error
    raise unless error.retryable? && attempts < @max_retries

    attempts += 1
    delay = capped_retry_delay(request, retry_delay(attempts))
    @on_retry.call(attempts, error, delay)
    wait_before_retry(request, delay)
    retry
  end
end