Class: Durable::Llm::Providers::Xai

Inherits:
Base
  • Object
show all
Defined in:
lib/durable/llm/providers/xai.rb

Overview

xAI provider for accessing xAI’s Grok language models.

This class provides methods to interact with xAI’s API for chat completions, embeddings, model listing, and streaming responses.

Defined Under Namespace

Classes: XaiChoice, XaiEmbeddingResponse, XaiMessage, XaiResponse, XaiStreamChoice, XaiStreamDelta, XaiStreamResponse

Constant Summary collapse

BASE_URL =
'https://api.x.ai/v1'

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

models, options, #stream?

Constructor Details

#initialize(api_key: nil) ⇒ Xai

Initializes the xAI provider with API key and HTTP connection.

Parameters:

  • api_key (String, nil) (defaults to: nil)

    The API key to use, defaults to default_api_key



41
42
43
44
45
46
47
48
# File 'lib/durable/llm/providers/xai.rb', line 41

def initialize(api_key: nil)
  super
  @conn = Faraday.new(url: BASE_URL) do |faraday|
    faraday.request :json
    faraday.response :json
    faraday.adapter Faraday.default_adapter
  end
end

Instance Attribute Details

#api_keyObject

Returns the value of attribute api_key.



36
37
38
# File 'lib/durable/llm/providers/xai.rb', line 36

def api_key
  @api_key
end

Class Method Details

.stream?Boolean

Indicates whether this provider supports streaming responses.

Returns:

  • (Boolean)

    Always true for xAI provider



92
93
94
# File 'lib/durable/llm/providers/xai.rb', line 92

def self.stream?
  true
end

Instance Method Details

#completion(options) ⇒ XaiResponse

Performs a chat completion request to xAI’s API.

Parameters:

  • options (Hash)

    The completion options including model, messages, etc.

Returns:



54
55
56
57
58
59
60
61
# File 'lib/durable/llm/providers/xai.rb', line 54

def completion(options)
  response = @conn.post('chat/completions') do |req|
    req.headers['Authorization'] = "Bearer #{@api_key}"
    req.body = options
  end

  handle_response(response)
end

#default_api_keyString?

Returns the default API key for xAI, checking configuration and environment variables.

Returns:

  • (String, nil)

    The API key or nil if not found



28
29
30
31
32
33
34
# File 'lib/durable/llm/providers/xai.rb', line 28

def default_api_key
  begin
    Durable::Llm.configuration.xai&.api_key
  rescue NoMethodError
    nil
  end || ENV['XAI_API_KEY']
end

#embedding(model:, input:, **options) ⇒ XaiEmbeddingResponse

Performs an embedding request to xAI’s API.

Parameters:

  • model (String)

    The embedding model to use

  • input (String, Array<String>)

    The text(s) to embed

  • options (Hash)

    Additional options for the embedding request

Returns:



69
70
71
72
73
74
75
76
# File 'lib/durable/llm/providers/xai.rb', line 69

def embedding(model:, input:, **options)
  response = @conn.post('embeddings') do |req|
    req.headers['Authorization'] = "Bearer #{@api_key}"
    req.body = { model: model, input: input, **options }
  end

  handle_response(response, XaiEmbeddingResponse)
end

#modelsArray<String>

Retrieves the list of available models from xAI’s API.

Returns:

  • (Array<String>)

    Array of model IDs



81
82
83
84
85
86
87
# File 'lib/durable/llm/providers/xai.rb', line 81

def models
  response = @conn.get('models') do |req|
    req.headers['Authorization'] = "Bearer #{@api_key}"
  end

  handle_response(response).data.map { |model| model['id'] }
end

#stream(options) {|XaiStreamResponse| ... } ⇒ nil

Performs a streaming chat completion request to xAI’s API.

Parameters:

  • options (Hash)

    The completion options including model, messages, etc.

Yields:

Returns:

  • (nil)

    Returns after streaming is complete



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/durable/llm/providers/xai.rb', line 101

def stream(options)
  options[:stream] = true

  response = @conn.post('chat/completions') do |req|
    req.headers['Authorization'] = "Bearer #{@api_key}"
    req.headers['Accept'] = 'text/event-stream'

    options['temperature'] = options['temperature'].to_f if options['temperature']

    req.body = options

    user_proc = proc do |chunk, _size, _total|
      yield XaiStreamResponse.new(chunk)
    end

    req.options.on_data = to_json_stream(user_proc: user_proc)
  end

  handle_response(response)
end