Class: Esp::Providers::Ollama
- Defined in:
- lib/esp/providers/ollama.rb
Overview
Ollama (local-runtime) provider. Talks to Ollama’s OpenAI-compatible Chat Completions endpoint (‘<base>/v1/chat/completions`), so it reuses the OpenAI provider’s request/response translation in full — the only differences are the base URL, a placeholder API key (the openai gem requires one but Ollama ignores it), and a reachability probe in place of “key is set” for the ‘configured?` semantic.
‘auto_default: false` at registration time means Ollama is never picked automatically — the user selects it explicitly in the UI, so a reachable local runtime doesn’t mask an un-keyed cloud provider.
Constant Summary collapse
- DEFAULT_MODEL =
'llama3.2'.freeze
- DEFAULT_BASE_URL =
'http://localhost:11434/v1'.freeze
- ENV_KEY =
'OLLAMA_BASE_URL'.freeze
- PROBE_TIMEOUT =
seconds — keep snappy, the UI hits this on /providers
0.25- PROBE_TTL =
cache reachability so refreshes don’t hammer Ollama
3.0
Class Method Summary collapse
-
.configured? ⇒ Boolean
‘configured?` = reachable, not “env set” — the base URL has a default, so the var being unset is the common case rather than misconfigured.
-
.list_models(base_url: nil) ⇒ Object
GET /api/tags → list of installed models for the model-input autocomplete (slice 3).
-
.reachable?(base_url: nil) ⇒ Boolean
GET /api/version against the configured base, with a tight timeout and a short-lived cache.
-
.reset_probe_cache! ⇒ Object
Cleared between tests so caching doesn’t leak between scenarios.
Instance Method Summary collapse
Methods inherited from OpenAI
Constructor Details
This class inherits a constructor from Esp::Providers::OpenAI
Class Method Details
.configured? ⇒ Boolean
‘configured?` = reachable, not “env set” — the base URL has a default, so the var being unset is the common case rather than misconfigured.
32 33 34 |
# File 'lib/esp/providers/ollama.rb', line 32 def configured? reachable? end |
.list_models(base_url: nil) ⇒ Object
GET /api/tags → list of installed models for the model-input autocomplete (slice 3). Returns [] on any failure — auto-discovery is convenience, not capability; if Ollama is down or slow the user still types the model name by hand.
60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/esp/providers/ollama.rb', line 60 def list_models(base_url: nil) url = base_url || ENV.fetch(ENV_KEY, DEFAULT_BASE_URL) uri = URI("#{url.sub(%r{/v1/?\z}, '')}/api/tags") res = Net::HTTP.start(uri.host, uri.port, open_timeout: PROBE_TIMEOUT, read_timeout: 2.0) do |http| http.get(uri.path.empty? ? '/api/tags' : uri.path) end return [] unless res.is_a?(Net::HTTPSuccess) (JSON.parse(res.body)['models'] || []).map { |m| m['name'] }.compact rescue StandardError [] end |
.reachable?(base_url: nil) ⇒ Boolean
GET /api/version against the configured base, with a tight timeout and a short-lived cache. Returns true iff Ollama answered 2xx.
38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/esp/providers/ollama.rb', line 38 def reachable?(base_url: nil) url = base_url || ENV.fetch(ENV_KEY, DEFAULT_BASE_URL) @probe_mutex.synchronize do now = Process.clock_gettime(Process::CLOCK_MONOTONIC) cached = @probe_cache[url] return cached[:value] if cached && now - cached[:at] < PROBE_TTL value = probe(url) @probe_cache[url] = { at: now, value: value } value end end |
.reset_probe_cache! ⇒ Object
Cleared between tests so caching doesn’t leak between scenarios.
52 53 54 |
# File 'lib/esp/providers/ollama.rb', line 52 def reset_probe_cache! @probe_mutex.synchronize { @probe_cache.clear } end |
Instance Method Details
#build_default_client ⇒ Object
89 90 91 92 93 94 95 96 |
# File 'lib/esp/providers/ollama.rb', line 89 def build_default_client require 'openai' ::OpenAI::Client.new( base_url: ENV.fetch(ENV_KEY, DEFAULT_BASE_URL), # The openai gem requires a non-nil api_key; Ollama ignores it. api_key: 'ollama' ) end |