Class: Ask::Providers::Ollama

Inherits:
Ask::Provider
  • Object
show all
Defined in:
lib/ask/provider/ollama.rb

Overview

Ollama provider for local LLM inference. Connects to a local Ollama server (default: localhost:11434).

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ Ollama

Returns a new instance of Ollama.



8
9
10
11
12
# File 'lib/ask/provider/ollama.rb', line 8

def initialize(config = {})
  config = normalize_config(config)
  super(config)
  @http = build_http
end

Class Method Details

.assume_models_exist?Boolean

Returns:

  • (Boolean)


59
# File 'lib/ask/provider/ollama.rb', line 59

def assume_models_exist?; true; end

.capabilitiesObject



52
53
54
# File 'lib/ask/provider/ollama.rb', line 52

def capabilities
  { chat: true, streaming: true, tool_calls: true, embed: true, local: true }
end

.configuration_optionsObject



55
# File 'lib/ask/provider/ollama.rb', line 55

def configuration_options; %i[api_base]; end

.configuration_requirementsObject



56
# File 'lib/ask/provider/ollama.rb', line 56

def configuration_requirements; %i[]; end

.local?Boolean

Returns:

  • (Boolean)


58
# File 'lib/ask/provider/ollama.rb', line 58

def local?; true; end

.slugObject



57
# File 'lib/ask/provider/ollama.rb', line 57

def slug; "ollama"; end

Instance Method Details

#api_baseObject



14
15
16
# File 'lib/ask/provider/ollama.rb', line 14

def api_base
  @config.api_base || "http://localhost:11434"
end

#chat(messages, model:, tools: nil, temperature: nil, stream: nil, schema: nil, **params, &block) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/ask/provider/ollama.rb', line 22

def chat(messages, model:, tools: nil, temperature: nil, stream: nil, schema: nil, **params, &block)
  msgs = messages.is_a?(Ask::Conversation) ? messages.to_a : messages
  payload = { model: model, messages: msgs.map { |m| { role: (m[:role] || m["role"]).to_s, content: m[:content] || m["content"] } }, stream: stream || false, options: {} }
  payload[:options][:temperature] = temperature if temperature
  if tools&.any?
    payload[:tools] = tools.map { |t| { type: "function", function: { name: t.respond_to?(:name) ? t.name : t[:name], description: t.respond_to?(:description) ? t.description : t[:description], parameters: t.respond_to?(:parameters) ? t.parameters : (t[:parameters] || {}) } } }
  end
  payload.merge(params)

  if stream
    chat_stream(payload, model, &block)
  else
    chat_nonstream(payload, model)
  end
end

#embed(texts, model:) ⇒ Object



38
39
40
41
42
43
# File 'lib/ask/provider/ollama.rb', line 38

def embed(texts, model:)
  texts = Array(texts)
  response = @http.post("api/embeddings") { |r| r.body = { model: model, prompt: texts.first } }
  raise LLM::HTTP.map_error(response.status, response.body, provider: "Ollama") unless response.success?
  Ask::Result.success(response.body["embedding"])
end

#headersObject



18
19
20
# File 'lib/ask/provider/ollama.rb', line 18

def headers
  { "Content-Type" => "application/json" }
end

#list_modelsObject



45
46
47
48
49
# File 'lib/ask/provider/ollama.rb', line 45

def list_models
  response = @http.get("api/tags")
  return [] unless response.success?
  response.body["models"].map { |m| Ask::ModelInfo.new(id: m["name"], provider: slug) }
end