Class: Prescient::Provider::Ollama
- Includes:
- HTTParty
- Defined in:
- lib/prescient/provider/ollama.rb
Overview
Ollama local or hosted API provider adapter.
Instance Attribute Summary
Attributes inherited from Base
Instance Method Summary collapse
-
#available_models ⇒ Array<Hash>
List models currently available from Ollama.
-
#generate_embedding(text, **_options) ⇒ Array<Float>
Generate an embedding through Ollama's
/api/embedendpoint. -
#generate_response(prompt, context_items = [], **options) ⇒ Hash
Generate text through Ollama's generation endpoint.
-
#health_check ⇒ Hash
Check whether the configured Ollama models are available locally.
-
#initialize(**options) ⇒ Ollama
constructor
A new instance of Ollama.
-
#pull_model(model_name) ⇒ Hash
Pull a model into the Ollama installation.
- #validate_configuration! ⇒ Object protected
Methods inherited from Base
#available?, #build_prompt, #clean_text, #default_context_configs, #default_prompt_templates, #extract_embedding_text, #extract_text_values, #format_context_item, #handle_errors, #validate_embedding_dimensions
Constructor Details
#initialize(**options) ⇒ Ollama
Returns a new instance of Ollama.
9 10 11 12 13 |
# File 'lib/prescient/provider/ollama.rb', line 9 def initialize(**) super self.class.base_uri(@options[:url]) self.class.default_timeout(@options[:timeout] || 60) end |
Instance Method Details
#available_models ⇒ Array<Hash>
List models currently available from Ollama.
114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/prescient/provider/ollama.rb', line 114 def available_models return @_available_models if defined?(@_available_models) handle_errors do @_available_models = (fetch_and_parse('get', '/api/tags', root_key: 'models') || []).map { |model| { embedding: model['name'] == @options[:embedding_model], chat: model['name'] == @options[:chat_model], name: model['name'], size: model['size'], modified_at: model['modified_at'], digest: model['digest'] } } end end |
#generate_embedding(text, **_options) ⇒ Array<Float>
Generate an embedding through Ollama's /api/embed endpoint.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/prescient/provider/ollama.rb', line 18 def (text, **) handle_errors do = fetch_and_parse('post', '/api/embed', root_key: 'embeddings', headers: { 'Content-Type' => 'application/json' }, body: { model: @options[:embedding_model], input: clean_text(text), }.to_json) = .is_a?(Array) ? .first : nil # : Array[Float]? raise Prescient::InvalidResponseError, 'No embedding returned' unless .is_a?(Array) expected_dimensions = @options[:embedding_dimensions] if expected_dimensions && .length != expected_dimensions raise Prescient::InvalidResponseError, "Invalid embedding dimensions: expected #{expected_dimensions}, got #{.length}" end end end |
#generate_response(prompt, context_items = [], **options) ⇒ Hash
Generate text through Ollama's generation endpoint.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/prescient/provider/ollama.rb', line 45 def generate_response(prompt, context_items = [], **) handle_errors do = prepare_generate_response(prompt, context_items, **) # Make the request and store both text and full response response = self.class.post('/api/generate', **) validate_response!(response, 'POST /api/generate') generated_text = response.parsed_response['response'] raise Prescient::InvalidResponseError, 'No response generated' unless generated_text { response: generated_text.strip, model: @options[:chat_model], provider: 'ollama', processing_time: response.parsed_response['total_duration']&./(1_000_000_000.0), metadata: { eval_count: response.parsed_response['eval_count'], eval_duration: response.parsed_response['eval_duration'], prompt_eval_count: response.parsed_response['prompt_eval_count'], }, } end end |
#health_check ⇒ Hash
Check whether the configured Ollama models are available locally.
reachable indicates the Ollama API answered successfully. ready
indicates that both configured models are present in the local model list.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/prescient/provider/ollama.rb', line 76 def health_check handle_errors do models = available_models = models.any? { |m| m[:embedding] } chat_available = models.any? { |m| m[:chat] } { status: 'healthy', provider: 'ollama', reachable: true, url: @options[:url], models_available: models.map { |m| m[:name] }, embedding_model: { name: @options[:embedding_model], available: , }, chat_model: { name: @options[:chat_model], available: chat_available, }, ready: && chat_available, } end rescue Prescient::Error => e { status: 'unavailable', provider: 'ollama', reachable: false, error: e.class.name, message: e., url: @options[:url], ready: false, } end |
#pull_model(model_name) ⇒ Hash
Pull a model into the Ollama installation.
129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/prescient/provider/ollama.rb', line 129 def pull_model(model_name) handle_errors do fetch_and_parse('post', '/api/pull', headers: { 'Content-Type' => 'application/json' }, body: { name: model_name }.to_json, timeout: 300) # 5 minutes for model download { success: true, model: model_name, message: "Model #{model_name} pulled successfully", } end end |
#validate_configuration! ⇒ Object (protected)
145 146 147 148 149 150 151 152 |
# File 'lib/prescient/provider/ollama.rb', line 145 def validate_configuration! = [:url, :embedding_model, :chat_model] = .select { |opt| @options[opt].nil? } return unless .any? raise Prescient::Error, "Missing required options: #{.join(', ')}" end |