Class: Llm::Client

Inherits:
Object
  • Object
show all
Defined in:
app/services/llm/client.rb

Defined Under Namespace

Classes: AllProvidersFailedError, NoCredentialsError

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(owner) ⇒ Client

Returns a new instance of Client.



31
32
33
# File 'app/services/llm/client.rb', line 31

def initialize(owner)
  @owner = owner
end

Class Method Details

.for(owner) ⇒ Object



27
28
29
# File 'app/services/llm/client.rb', line 27

def self.for(owner)
  new(owner)
end

Instance Method Details

#call_tool(system:, tool:, max_tokens:, content_blocks: nil, messages: nil) ⇒ Object

Raises:



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'app/services/llm/client.rb', line 35

def call_tool(system:, tool:, max_tokens:, content_blocks: nil, messages: nil)
  needs_vision = content_blocks&.any? { |block| block[:kind] == :image } || false

  credentials = @owner.llm_credentials.ranked.to_a
  credentials = credentials.select { |c| Llm::ProviderRegistry.vision_capable?(c.provider, c.model) } if needs_vision
  raise NoCredentialsError, "No configured AI API credential can handle this request" if credentials.empty?

  last_error = nil
  credentials.each do |credential|
    result = adapter_for(credential).call_tool(system: system, tool: tool, max_tokens: max_tokens, content_blocks: content_blocks, messages: messages)
    record_usage(credential, result)
    return result.data
  rescue StandardError => e
    last_error = e
    Rails.logger.warn("Llm::Client: #{credential.provider}/#{credential.model} failed (#{e.class}: #{e.message}), trying next")
  end

  raise AllProvidersFailedError, "All #{credentials.size} configured AI API credential(s) failed. Last error: #{last_error.class}: #{last_error.message}"
end