Module: Esp::Providers
- Defined in:
- lib/esp/providers.rb,
lib/esp/providers/ollama.rb,
lib/esp/providers/openai.rb,
lib/esp/providers/anthropic.rb
Overview
The LLM-provider seam behind Esp::Agent. Each provider translates the agent’s neutral transcript to its API’s native wire shape and normalizes the response back to a Completion. Providers self-register here, so adding one is a new file under providers/ plus a require in the load manifest.
Provider contract:
#complete(system:, tools:, messages:) -> Completion(text:, tool_calls:, raw:)
system — String system prompt
tools — Array<{name:, description:, input_schema:}> (JSON-Schema)
messages — the neutral transcript (see Esp::Agent)
raw — the provider-native assistant *message* for this turn, stored
on the assistant entry and replayed verbatim next call so
provider-side state (Anthropic thinking signatures, OpenAI
tool_calls) survives multi-turn tool use.
Defined Under Namespace
Classes: Anthropic, Completion, Entry, Ollama, OpenAI, UnknownProvider
Class Method Summary collapse
-
.available ⇒ Object
The providers a client can choose from: id, default model, and whether each provider considers itself configured (per its own ‘configured?` — env-key presence for cloud providers, reachability probe for local).
-
.build(id, model: nil) ⇒ Object
Instantiate a provider by id, with an optional model override (blank → the provider’s default).
-
.default_id ⇒ Object
The provider to use when the caller doesn’t pick one: an explicit ESP_PROVIDER override (legacy MW_PROVIDER still honoured until step 24 ships), else the first auto-default configured provider, else the first registered.
-
.register(id, klass, default_model:, env_key:, auto_default: true) ⇒ Object
Providers call this at load time.
-
.registry ⇒ Object
The id → Entry map, lazily initialized and populated by providers at load time (a plain mutable hash, hence not a frozen constant).
Class Method Details
.available ⇒ Object
The providers a client can choose from: id, default model, and whether each provider considers itself configured (per its own ‘configured?` — env-key presence for cloud providers, reachability probe for local).
55 56 57 58 59 60 |
# File 'lib/esp/providers.rb', line 55 def available registry.values.map do |entry| { id: entry.id, default_model: entry.default_model.to_s, configured: entry.klass.configured? } end end |
.build(id, model: nil) ⇒ Object
Instantiate a provider by id, with an optional model override (blank →the provider’s default). Extra opts (e.g. an injected client) pass through for tests.
46 47 48 49 50 |
# File 'lib/esp/providers.rb', line 46 def build(id, model: nil, **) entry = registry.fetch(id.to_s) { raise UnknownProvider, Esp.t('errors.providers.unknown', id: id) } chosen = model.nil? || model.to_s.empty? ? entry.default_model : model entry.klass.new(model: chosen, **) end |
.default_id ⇒ Object
The provider to use when the caller doesn’t pick one: an explicit ESP_PROVIDER override (legacy MW_PROVIDER still honoured until step 24 ships), else the first auto-default configured provider, else the first registered. Manual-only providers (Ollama) are excluded from automatic selection — see Entry#auto_default.
67 68 69 70 71 72 73 |
# File 'lib/esp/providers.rb', line 67 def default_id override = ENV['ESP_PROVIDER'] || ENV.fetch('MW_PROVIDER', nil) return override if registry.key?(override.to_s) preferred = registry.values.find { |entry| entry.auto_default && entry.klass.configured? } preferred ? preferred.id : registry.keys.first end |
.register(id, klass, default_model:, env_key:, auto_default: true) ⇒ Object
Providers call this at load time. ‘env_key` names the environment variable that carries the API key (the shell injects it per provider). Provider classes must define `self.configured?` — usually “env key set” for cloud providers, “reachable” for local runtimes. `auto_default: false` keeps a provider out of automatic default selection (used by Ollama so the user picks it explicitly).
38 39 40 41 |
# File 'lib/esp/providers.rb', line 38 def register(id, klass, default_model:, env_key:, auto_default: true) registry[id] = Entry.new(id: id, klass: klass, default_model: default_model, env_key: env_key, auto_default: auto_default) end |
.registry ⇒ Object
The id → Entry map, lazily initialized and populated by providers at load time (a plain mutable hash, hence not a frozen constant).
28 29 30 |
# File 'lib/esp/providers.rb', line 28 def registry @registry ||= {} end |