Class: Durable::Llm::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/durable/llm/client.rb

Overview

Unified interface for interacting with different LLM providers

The Client class provides a facade that delegates operations like completion, chat, embedding, and streaming to the appropriate provider instance while handling parameter processing, model configuration, and providing convenience methods for quick text completion. The client automatically resolves provider classes based on the provider name and manages default parameters including model selection.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(provider_name, options = {}) ⇒ Client

Initializes a new LLM client for the specified provider

Parameters:

  • provider_name (Symbol, String)

    The name of the LLM provider (e.g., :openai, :anthropic)

  • options (Hash) (defaults to: {})

    Configuration options for the provider and client

Options Hash (options):

  • :model (String)

    The default model to use for requests

  • 'model' (String)

    Alternative string key for model

  • :api_key (String)

    API key for authentication (provider-specific)

Raises:

  • (NameError)

    If the provider class cannot be found



37
38
39
40
41
42
43
# File 'lib/durable/llm/client.rb', line 37

def initialize(provider_name, options = {})
  @model = options.delete('model') || options.delete(:model) if options.key?('model') || options.key?(:model)

  provider_class = Durable::Llm::Providers.provider_class_for(provider_name)

  @provider = provider_class.new(**options)
end

Instance Attribute Details

#modelString?

Returns The default model to use for requests.

Returns:

  • (String, nil)

    The default model to use for requests



27
28
29
# File 'lib/durable/llm/client.rb', line 27

def model
  @model
end

#providerObject (readonly)

Returns The underlying provider instance.

Returns:

  • (Object)

    The underlying provider instance



24
25
26
# File 'lib/durable/llm/client.rb', line 24

def provider
  @provider
end

Instance Method Details

#chat(params = {}) ⇒ Object

Performs a chat completion request (alias for completion)

Parameters:

  • params (Hash) (defaults to: {})

    The chat parameters

Returns:

  • (Object)

    The chat response object

Raises:



89
90
91
# File 'lib/durable/llm/client.rb', line 89

def chat(params = {})
  @provider.completion(process_params(params))
end

#completion(params = {}) ⇒ Object

Performs a completion request

Parameters:

  • params (Hash) (defaults to: {})

    The completion parameters

Returns:

  • (Object)

    The completion response object

Raises:



80
81
82
# File 'lib/durable/llm/client.rb', line 80

def completion(params = {})
  @provider.completion(process_params(params))
end

#default_paramsHash

Returns the default parameters to merge with request options

Returns:

  • (Hash)

    Default parameters including model if set



48
49
50
# File 'lib/durable/llm/client.rb', line 48

def default_params
  @model ? { model: @model } : {}
end

#embed(params = {}) ⇒ Object

Performs an embedding request

Parameters:

  • params (Hash) (defaults to: {})

    The embedding parameters including model and input

Returns:

  • (Object)

    The embedding response object

Raises:

  • (NotImplementedError)

    If the provider doesn’t support embeddings

  • (Durable::Llm::APIError)

    If the API request fails



99
100
101
102
103
# File 'lib/durable/llm/client.rb', line 99

def embed(params = {})
  @provider.embedding(**process_params(params))
rescue NotImplementedError
  raise NotImplementedError, "#{@provider.class.name} does not support embeddings"
end

#quick_complete(text, _opts = {}) ⇒ String

Performs a quick text completion with minimal configuration

Parameters:

  • text (String)

    The input text to complete

  • opts (Hash)

    Additional options (currently unused, reserved for future use)

Returns:

  • (String)

    The generated completion text

Raises:

  • (Durable::Llm::APIError)

    If the API request fails

  • (IndexError)

    If the response contains no choices

  • (NoMethodError)

    If the response structure is unexpected



60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/durable/llm/client.rb', line 60

def quick_complete(text, _opts = {})
  response = completion(process_params(messages: [{ role: 'user', content: text }]))

  choice = response.choices.first
  raise IndexError, 'No completion choices returned' unless choice

  message = choice.message
  raise NoMethodError, 'Response choice has no message' unless message

  content = message.content
  raise NoMethodError, 'Response message has no content' unless content

  content
end

#stream(params = {}) {|Object| ... } ⇒ Object

Performs a streaming completion request

Parameters:

  • params (Hash) (defaults to: {})

    The streaming parameters

Yields:

  • (Object)

    Yields stream response chunks as they arrive

Returns:

  • (Object)

    The final response object

Raises:

  • (NotImplementedError)

    If the provider doesn’t support streaming

  • (Durable::Llm::APIError)

    If the API request fails



112
113
114
115
116
# File 'lib/durable/llm/client.rb', line 112

def stream(params = {}, &block)
  @provider.stream(process_params(params), &block)
rescue NotImplementedError
  raise NotImplementedError, "#{@provider.class.name} does not support streaming"
end

#stream?Boolean

Checks if the provider supports streaming

Returns:

  • (Boolean)

    True if streaming is supported, false otherwise



121
122
123
# File 'lib/durable/llm/client.rb', line 121

def stream?
  @provider.stream?
end