Class: SkillBench::Client

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

Overview

Facade for calling LLM clients. Delegates to the configured provider.

Constant Summary collapse

UNCACHEABLE_CLIENTS =

Provider clients that must never be cached: their results either signal a configuration error (NullClient) or are cheap, deterministic test doubles (Mock). Caching them would provide no benefit and could mask errors.

[
  Clients::Providers::NullClient,
  Clients::Providers::Mock
].freeze

Class Method Summary collapse

Class Method Details

.call(system_prompt:, messages:, provider: nil, **options) ⇒ Hash

Calls the configured LLM provider with the given parameters.

When response caching is enabled (see Services::ResponseCache.enabled?) and the resolved provider is cacheable, identical requests reuse a cached response instead of calling the provider again. When caching is disabled (the default), the provider is always invoked, leaving behavior unchanged.

Parameters:

  • system_prompt (String)

    System prompt for the LLM

  • messages (Array<Hash>)

    Conversation messages

  • provider (Symbol, nil) (defaults to: nil)

    Override the configured LLM provider (e.g., :deepseek, :openai)

  • options (Hash)

    Provider-specific options (api_key, model, etc.)

Returns:

  • (Hash)

    Response from the LLM



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/skill_bench/client.rb', line 30

def self.call(system_prompt:, messages:, provider: nil, **options)
  resolved = provider || Config.current_llm_provider || :openai
  client_class = Clients::ProviderRegistry.for(resolved)
  warn "WARNING: LLM provider '#{resolved}' is not configured. Falling back to null client." if client_class == Clients::Providers::NullClient

  invoke = -> { client_class.call(system_prompt: system_prompt, messages: messages, **options) }
  return invoke.call unless cache_eligible?(client_class)

  cache_key = Services::ResponseCache.key(
    provider: resolved,
    model: options[:model],
    system_prompt: system_prompt,
    messages: messages,
    tools: options[:tools],
    temperature: options[:temperature],
    provider_config: options.slice(:base_url, :request_path, :endpoint, :location, :project_id, :api_version)
  )
  Services::ResponseCache.fetch(cache_key, &invoke)
end