prescient 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +0 -2
- data/.yardopts +3 -6
- data/CHANGELOG.md +41 -4
- data/INTEGRATION_GUIDE.md +27 -29
- data/LICENSE.txt +1 -1
- data/README.md +133 -74
- data/Rakefile +82 -7
- data/Steepfile +17 -0
- data/VECTOR_SEARCH_GUIDE.md +32 -8
- data/docker-compose.yml +3 -5
- data/examples/README.md +45 -0
- data/examples/basic_usage.rb +2 -2
- data/examples/custom_contexts.rb +6 -6
- data/examples/custom_prompts.rb +5 -5
- data/examples/vector_search.rb +2 -2
- data/lib/prescient/base.rb +81 -26
- data/lib/prescient/client.rb +70 -36
- data/lib/prescient/errors.rb +51 -0
- data/lib/prescient/pgvector.rb +194 -0
- data/lib/prescient/provider/anthropic.rb +55 -54
- data/lib/prescient/provider/huggingface.rb +76 -76
- data/lib/prescient/provider/ollama.rb +46 -35
- data/lib/prescient/provider/openai.rb +38 -31
- data/lib/prescient/version.rb +2 -1
- data/lib/prescient.rb +85 -63
- data/scripts/setup-ollama-models.sh +2 -2
- data/sig/prescient.rbs +221 -1
- metadata +21 -217
- data/CHANGELOG.pdf +0 -0
- data/prescient.gemspec +0 -53
|
@@ -2,33 +2,46 @@
|
|
|
2
2
|
|
|
3
3
|
require 'httparty'
|
|
4
4
|
|
|
5
|
+
# Ollama local or hosted API provider adapter.
|
|
5
6
|
class Prescient::Provider::Ollama < Prescient::Base
|
|
6
7
|
include HTTParty
|
|
7
8
|
|
|
8
|
-
EMBEDDING_DIMENSIONS = 768 # nomic-embed-text dimensions
|
|
9
|
-
|
|
10
9
|
def initialize(**options)
|
|
11
10
|
super
|
|
12
11
|
self.class.base_uri(@options[:url])
|
|
13
12
|
self.class.default_timeout(@options[:timeout] || 60)
|
|
14
13
|
end
|
|
15
14
|
|
|
15
|
+
# Generate an embedding through Ollama's `/api/embed` endpoint.
|
|
16
|
+
# @param text [String] Text to embed
|
|
17
|
+
# @return [Array<Float>] Embedding vector from the first returned input item
|
|
16
18
|
def generate_embedding(text, **_options)
|
|
17
19
|
handle_errors do
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
20
|
+
embeddings = fetch_and_parse('post', '/api/embed',
|
|
21
|
+
root_key: 'embeddings',
|
|
22
|
+
headers: { 'Content-Type' => 'application/json' },
|
|
23
|
+
body: {
|
|
24
|
+
model: @options[:embedding_model],
|
|
25
|
+
input: clean_text(text),
|
|
26
|
+
}.to_json)
|
|
27
|
+
|
|
28
|
+
embedding = embeddings.is_a?(Array) ? embeddings.first : nil # : Array[Float]?
|
|
29
|
+
raise Prescient::InvalidResponseError, 'No embedding returned' unless embedding.is_a?(Array)
|
|
30
|
+
|
|
31
|
+
expected_dimensions = @options[:embedding_dimensions]
|
|
32
|
+
if expected_dimensions && embedding.length != expected_dimensions
|
|
33
|
+
raise Prescient::InvalidResponseError,
|
|
34
|
+
"Invalid embedding dimensions: expected #{expected_dimensions}, got #{embedding.length}"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
embedding
|
|
29
38
|
end
|
|
30
39
|
end
|
|
31
40
|
|
|
41
|
+
# Generate text through Ollama's generation endpoint.
|
|
42
|
+
# @param prompt [String] Prompt to send
|
|
43
|
+
# @param context_items [Array<Hash, String>] Optional context items
|
|
44
|
+
# @return [Hash] Normalized response data
|
|
32
45
|
def generate_response(prompt, context_items = [], **options)
|
|
33
46
|
handle_errors do
|
|
34
47
|
request_options = prepare_generate_response(prompt, context_items, **options)
|
|
@@ -54,6 +67,12 @@ class Prescient::Provider::Ollama < Prescient::Base
|
|
|
54
67
|
end
|
|
55
68
|
end
|
|
56
69
|
|
|
70
|
+
# Check whether the configured Ollama models are available locally.
|
|
71
|
+
#
|
|
72
|
+
# `reachable` indicates the Ollama API answered successfully. `ready`
|
|
73
|
+
# indicates that both configured models are present in the local model list.
|
|
74
|
+
#
|
|
75
|
+
# @return [Hash] Provider health information
|
|
57
76
|
def health_check
|
|
58
77
|
handle_errors do
|
|
59
78
|
models = available_models
|
|
@@ -63,6 +82,7 @@ class Prescient::Provider::Ollama < Prescient::Base
|
|
|
63
82
|
{
|
|
64
83
|
status: 'healthy',
|
|
65
84
|
provider: 'ollama',
|
|
85
|
+
reachable: true,
|
|
66
86
|
url: @options[:url],
|
|
67
87
|
models_available: models.map { |m| m[:name] },
|
|
68
88
|
embedding_model: {
|
|
@@ -78,14 +98,19 @@ class Prescient::Provider::Ollama < Prescient::Base
|
|
|
78
98
|
end
|
|
79
99
|
rescue Prescient::Error => e
|
|
80
100
|
{
|
|
81
|
-
status:
|
|
82
|
-
provider:
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
101
|
+
status: 'unavailable',
|
|
102
|
+
provider: 'ollama',
|
|
103
|
+
reachable: false,
|
|
104
|
+
error: e.class.name,
|
|
105
|
+
message: e.message,
|
|
106
|
+
url: @options[:url],
|
|
107
|
+
ready: false,
|
|
86
108
|
}
|
|
87
109
|
end
|
|
88
110
|
|
|
111
|
+
# List models currently available from Ollama.
|
|
112
|
+
# @return [Array<Hash>] Model descriptors including name, size, digest,
|
|
113
|
+
# modified_at, and booleans for configured embedding/chat roles
|
|
89
114
|
def available_models
|
|
90
115
|
return @_available_models if defined?(@_available_models)
|
|
91
116
|
|
|
@@ -98,6 +123,9 @@ class Prescient::Provider::Ollama < Prescient::Base
|
|
|
98
123
|
end
|
|
99
124
|
end
|
|
100
125
|
|
|
126
|
+
# Pull a model into the Ollama installation.
|
|
127
|
+
# @param model_name [String] Model identifier to download
|
|
128
|
+
# @return [Hash] Pull result
|
|
101
129
|
def pull_model(model_name)
|
|
102
130
|
handle_errors do
|
|
103
131
|
fetch_and_parse('post', '/api/pull',
|
|
@@ -152,21 +180,4 @@ class Prescient::Provider::Ollama < Prescient::Base
|
|
|
152
180
|
response.parsed_response[root_key]
|
|
153
181
|
end
|
|
154
182
|
|
|
155
|
-
def validate_response!(response, operation)
|
|
156
|
-
return if response.success?
|
|
157
|
-
|
|
158
|
-
case response.code
|
|
159
|
-
when 404
|
|
160
|
-
raise Prescient::ModelNotAvailableError, "Model not available for #{operation}"
|
|
161
|
-
when 429
|
|
162
|
-
raise Prescient::RateLimitError, "Rate limit exceeded for #{operation}"
|
|
163
|
-
when 401, 403
|
|
164
|
-
raise Prescient::AuthenticationError, "Authentication failed for #{operation}"
|
|
165
|
-
when 500..599
|
|
166
|
-
raise Prescient::Error, "Ollama server error during #{operation}: #{response.body}"
|
|
167
|
-
else
|
|
168
|
-
raise Prescient::Error,
|
|
169
|
-
"Ollama request failed for #{operation}: HTTP #{response.code} - #{response.message}"
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
183
|
end
|
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
require 'httparty'
|
|
4
4
|
|
|
5
|
+
# OpenAI API provider adapter.
|
|
5
6
|
class Prescient::Provider::OpenAI < Prescient::Base
|
|
6
7
|
include HTTParty
|
|
7
8
|
|
|
8
9
|
base_uri 'https://api.openai.com'
|
|
9
10
|
|
|
11
|
+
# Known embedding dimensions for OpenAI embedding models.
|
|
10
12
|
EMBEDDING_DIMENSIONS = {
|
|
11
13
|
'text-embedding-3-small' => 1536,
|
|
12
14
|
'text-embedding-3-large' => 3072,
|
|
@@ -18,6 +20,9 @@ class Prescient::Provider::OpenAI < Prescient::Base
|
|
|
18
20
|
self.class.default_timeout(@options[:timeout] || 60)
|
|
19
21
|
end
|
|
20
22
|
|
|
23
|
+
# Generate an embedding through the OpenAI embeddings API.
|
|
24
|
+
# @param text [String] Text to embed
|
|
25
|
+
# @return [Array<Float>] Embedding vector
|
|
21
26
|
def generate_embedding(text, **_options)
|
|
22
27
|
handle_errors do
|
|
23
28
|
clean_text_input = clean_text(text)
|
|
@@ -38,11 +43,20 @@ class Prescient::Provider::OpenAI < Prescient::Base
|
|
|
38
43
|
embedding_data = response.parsed_response.dig('data', 0, 'embedding')
|
|
39
44
|
raise Prescient::InvalidResponseError, 'No embedding returned' unless embedding_data
|
|
40
45
|
|
|
41
|
-
expected_dimensions = EMBEDDING_DIMENSIONS[@options[:embedding_model]] ||
|
|
42
|
-
|
|
46
|
+
expected_dimensions = EMBEDDING_DIMENSIONS[@options[:embedding_model]] || @options[:embedding_dimensions]
|
|
47
|
+
unless expected_dimensions
|
|
48
|
+
raise Prescient::Error,
|
|
49
|
+
"Embedding dimensions are required for model #{@options[:embedding_model]}"
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
validate_embedding_dimensions(embedding_data, expected_dimensions)
|
|
43
53
|
end
|
|
44
54
|
end
|
|
45
55
|
|
|
56
|
+
# Generate a response through the OpenAI chat completions API.
|
|
57
|
+
# @param prompt [String] Prompt to send
|
|
58
|
+
# @param context_items [Array<Hash, String>] Optional context items
|
|
59
|
+
# @return [Hash] Normalized response data
|
|
46
60
|
def generate_response(prompt, context_items = [], **options)
|
|
47
61
|
handle_errors do
|
|
48
62
|
formatted_prompt = build_prompt(prompt, context_items)
|
|
@@ -83,6 +97,12 @@ class Prescient::Provider::OpenAI < Prescient::Base
|
|
|
83
97
|
end
|
|
84
98
|
end
|
|
85
99
|
|
|
100
|
+
# Check OpenAI model availability via `/v1/models`.
|
|
101
|
+
#
|
|
102
|
+
# `reachable` indicates the API answered successfully. `ready` indicates that
|
|
103
|
+
# both configured models appear in the returned model list.
|
|
104
|
+
#
|
|
105
|
+
# @return [Hash] Provider health information
|
|
86
106
|
def health_check
|
|
87
107
|
handle_errors do
|
|
88
108
|
response = self.class.get('/v1/models',
|
|
@@ -98,6 +118,7 @@ class Prescient::Provider::OpenAI < Prescient::Base
|
|
|
98
118
|
{
|
|
99
119
|
status: 'healthy',
|
|
100
120
|
provider: 'openai',
|
|
121
|
+
reachable: true,
|
|
101
122
|
models_available: models.map { |m| m['id'] },
|
|
102
123
|
embedding_model: {
|
|
103
124
|
name: @options[:embedding_model],
|
|
@@ -111,22 +132,29 @@ class Prescient::Provider::OpenAI < Prescient::Base
|
|
|
111
132
|
}
|
|
112
133
|
else
|
|
113
134
|
{
|
|
114
|
-
status:
|
|
115
|
-
provider:
|
|
116
|
-
|
|
117
|
-
|
|
135
|
+
status: 'unhealthy',
|
|
136
|
+
provider: 'openai',
|
|
137
|
+
reachable: true,
|
|
138
|
+
error: "HTTP #{response.code}",
|
|
139
|
+
message: response.message,
|
|
140
|
+
ready: false,
|
|
118
141
|
}
|
|
119
142
|
end
|
|
120
143
|
end
|
|
121
144
|
rescue Prescient::Error => e
|
|
122
145
|
{
|
|
123
|
-
status:
|
|
124
|
-
provider:
|
|
125
|
-
|
|
126
|
-
|
|
146
|
+
status: 'unavailable',
|
|
147
|
+
provider: 'openai',
|
|
148
|
+
reachable: false,
|
|
149
|
+
error: e.class.name,
|
|
150
|
+
message: e.message,
|
|
151
|
+
ready: false,
|
|
127
152
|
}
|
|
128
153
|
end
|
|
129
154
|
|
|
155
|
+
# List models available to the configured OpenAI account.
|
|
156
|
+
#
|
|
157
|
+
# @return [Array<Hash>] Model descriptors
|
|
130
158
|
def list_models
|
|
131
159
|
handle_errors do
|
|
132
160
|
response = self.class.get('/v1/models',
|
|
@@ -157,25 +185,4 @@ class Prescient::Provider::OpenAI < Prescient::Base
|
|
|
157
185
|
raise Prescient::Error, "Missing required options: #{missing_options.join(', ')}"
|
|
158
186
|
end
|
|
159
187
|
|
|
160
|
-
private
|
|
161
|
-
|
|
162
|
-
def validate_response!(response, operation)
|
|
163
|
-
return if response.success?
|
|
164
|
-
|
|
165
|
-
case response.code
|
|
166
|
-
when 400
|
|
167
|
-
raise Prescient::Error, "Bad request for #{operation}: #{response.body}"
|
|
168
|
-
when 401
|
|
169
|
-
raise Prescient::AuthenticationError, "Authentication failed for #{operation}"
|
|
170
|
-
when 403
|
|
171
|
-
raise Prescient::AuthenticationError, "Forbidden access for #{operation}"
|
|
172
|
-
when 429
|
|
173
|
-
raise Prescient::RateLimitError, "Rate limit exceeded for #{operation}"
|
|
174
|
-
when 500..599
|
|
175
|
-
raise Prescient::Error, "OpenAI server error during #{operation}: #{response.body}"
|
|
176
|
-
else
|
|
177
|
-
raise Prescient::Error,
|
|
178
|
-
"OpenAI request failed for #{operation}: HTTP #{response.code} - #{response.message}"
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
188
|
end
|
data/lib/prescient/version.rb
CHANGED
data/lib/prescient.rb
CHANGED
|
@@ -1,11 +1,19 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require_relative 'prescient/version'
|
|
4
|
+
require_relative 'prescient/errors'
|
|
5
|
+
require_relative 'prescient/pgvector'
|
|
6
|
+
require_relative 'prescient/base'
|
|
7
|
+
require_relative 'prescient/provider/ollama'
|
|
8
|
+
require_relative 'prescient/provider/anthropic'
|
|
9
|
+
require_relative 'prescient/provider/openai'
|
|
10
|
+
require_relative 'prescient/provider/huggingface'
|
|
11
|
+
require_relative 'prescient/client'
|
|
4
12
|
|
|
5
13
|
# Main Prescient module for AI provider abstraction
|
|
6
14
|
#
|
|
7
15
|
# Prescient provides a unified interface for working with multiple AI providers
|
|
8
|
-
# including Ollama, OpenAI, Anthropic, and
|
|
16
|
+
# including Ollama, OpenAI, Anthropic, and Hugging Face. It supports both
|
|
9
17
|
# embedding generation and text completion with configurable context handling.
|
|
10
18
|
#
|
|
11
19
|
# @example Basic usage
|
|
@@ -20,44 +28,6 @@ require_relative 'prescient/version'
|
|
|
20
28
|
# @example Embedding generation
|
|
21
29
|
# embedding = client.generate_embedding("Some text to embed")
|
|
22
30
|
# puts embedding.length # => 1536 (for OpenAI text-embedding-3-small)
|
|
23
|
-
#
|
|
24
|
-
# @author Claude Code
|
|
25
|
-
# @since 1.0.0
|
|
26
|
-
module Prescient
|
|
27
|
-
# Base error class for all Prescient-specific errors
|
|
28
|
-
class Error < StandardError; end
|
|
29
|
-
|
|
30
|
-
# Raised when there are connection issues with AI providers
|
|
31
|
-
class ConnectionError < Error; end
|
|
32
|
-
|
|
33
|
-
# Raised when API authentication fails
|
|
34
|
-
class AuthenticationError < Error; end
|
|
35
|
-
|
|
36
|
-
# Raised when API rate limits are exceeded
|
|
37
|
-
class RateLimitError < Error; end
|
|
38
|
-
|
|
39
|
-
# Raised when a requested model is not available
|
|
40
|
-
class ModelNotAvailableError < Error; end
|
|
41
|
-
|
|
42
|
-
# Raised when AI provider returns invalid or malformed responses
|
|
43
|
-
class InvalidResponseError < Error; end
|
|
44
|
-
|
|
45
|
-
# Container module for AI provider implementations
|
|
46
|
-
#
|
|
47
|
-
# All provider classes should be defined within this module and inherit
|
|
48
|
-
# from {Prescient::Base}.
|
|
49
|
-
module Provider
|
|
50
|
-
# Module for AI provider implementations
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
require_relative 'prescient/base'
|
|
55
|
-
require_relative 'prescient/provider/ollama'
|
|
56
|
-
require_relative 'prescient/provider/anthropic'
|
|
57
|
-
require_relative 'prescient/provider/openai'
|
|
58
|
-
require_relative 'prescient/provider/huggingface'
|
|
59
|
-
require_relative 'prescient/client'
|
|
60
|
-
|
|
61
31
|
module Prescient
|
|
62
32
|
# Configure Prescient with custom settings and providers
|
|
63
33
|
#
|
|
@@ -95,6 +65,9 @@ module Prescient
|
|
|
95
65
|
# Handles global settings like timeouts and retry behavior, as well as
|
|
96
66
|
# provider registration and instantiation.
|
|
97
67
|
class Configuration
|
|
68
|
+
# @return [Array<Symbol>] Built-in provider option keys removed from output
|
|
69
|
+
DEFAULT_SENSITIVE_KEYS = [:api_key, :password, :token, :secret].freeze
|
|
70
|
+
|
|
98
71
|
# @return [Symbol] The default provider to use when none specified
|
|
99
72
|
attr_accessor :default_provider
|
|
100
73
|
|
|
@@ -110,6 +83,9 @@ module Prescient
|
|
|
110
83
|
# @return [Array<Symbol>] List of fallback providers to try when primary fails
|
|
111
84
|
attr_accessor :fallback_providers
|
|
112
85
|
|
|
86
|
+
# @return [Array<Symbol>] Additional keys removed from provider information
|
|
87
|
+
attr_reader :sensitive_keys
|
|
88
|
+
|
|
113
89
|
# @return [Hash] Registered providers configuration
|
|
114
90
|
attr_reader :providers
|
|
115
91
|
|
|
@@ -120,7 +96,18 @@ module Prescient
|
|
|
120
96
|
@retry_attempts = 3
|
|
121
97
|
@retry_delay = 1.0
|
|
122
98
|
@fallback_providers = []
|
|
99
|
+
@sensitive_keys = []
|
|
123
100
|
@providers = {}
|
|
101
|
+
@provider_instances = {} # : Hash[Symbol, untyped]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Configure additional keys to remove from provider information.
|
|
105
|
+
# Built-in sensitive keys are always sanitized.
|
|
106
|
+
#
|
|
107
|
+
# @param keys [Array<Symbol, String>] Additional sensitive option keys
|
|
108
|
+
# @return [Array<Symbol>] Normalized additional keys
|
|
109
|
+
def sensitive_keys=(keys)
|
|
110
|
+
@sensitive_keys = Array(keys).map(&:to_sym).uniq
|
|
124
111
|
end
|
|
125
112
|
|
|
126
113
|
# Register a new AI provider
|
|
@@ -137,12 +124,14 @@ module Prescient
|
|
|
137
124
|
# @example Add OpenAI provider
|
|
138
125
|
# config.add_provider(:openai, Prescient::Provider::OpenAI,
|
|
139
126
|
# api_key: 'sk-...',
|
|
140
|
-
# chat_model: 'gpt-4')
|
|
127
|
+
# chat_model: 'gpt-4.1-mini')
|
|
141
128
|
def add_provider(name, provider_class, **options)
|
|
142
|
-
|
|
129
|
+
provider_name = name.to_sym
|
|
130
|
+
@providers[provider_name] = {
|
|
143
131
|
class: provider_class,
|
|
144
132
|
options: options,
|
|
145
133
|
}
|
|
134
|
+
@provider_instances.delete(provider_name)
|
|
146
135
|
end
|
|
147
136
|
|
|
148
137
|
# Instantiate a provider by name
|
|
@@ -150,15 +139,20 @@ module Prescient
|
|
|
150
139
|
# @param name [Symbol] The provider name
|
|
151
140
|
# @return [Base, nil] Provider instance or nil if not found
|
|
152
141
|
def provider(name)
|
|
153
|
-
|
|
142
|
+
provider_name = name.to_sym
|
|
143
|
+
provider_config = @providers[provider_name]
|
|
154
144
|
return nil unless provider_config
|
|
155
145
|
|
|
156
|
-
provider_config[:
|
|
146
|
+
provider_options = provider_config[:options] # : Hash[Symbol, untyped]
|
|
147
|
+
@provider_instances[provider_name] ||= provider_config[:class].new(**provider_options)
|
|
157
148
|
end
|
|
158
149
|
|
|
159
|
-
# Get list of
|
|
150
|
+
# Get list of providers that currently pass {Prescient::Base#available?}.
|
|
151
|
+
#
|
|
152
|
+
# Providers are included when their health check reports `reachable: true`,
|
|
153
|
+
# or, for legacy adapters, `status == "healthy"`.
|
|
160
154
|
#
|
|
161
|
-
# @return [Array<Symbol>] List of
|
|
155
|
+
# @return [Array<Symbol>] List of reachable provider names
|
|
162
156
|
def available_providers
|
|
163
157
|
@providers.keys.select do |name|
|
|
164
158
|
provider(name)&.available?
|
|
@@ -168,25 +162,53 @@ module Prescient
|
|
|
168
162
|
end
|
|
169
163
|
end
|
|
170
164
|
|
|
165
|
+
class << self
|
|
166
|
+
private
|
|
167
|
+
|
|
168
|
+
def configure_default_providers(config, env)
|
|
169
|
+
config.add_provider(:ollama,
|
|
170
|
+
Prescient::Provider::Ollama,
|
|
171
|
+
url: env.fetch('OLLAMA_URL', 'http://localhost:11434'),
|
|
172
|
+
embedding_model: env.fetch('OLLAMA_EMBEDDING_MODEL', 'nomic-embed-text'),
|
|
173
|
+
chat_model: env.fetch('OLLAMA_CHAT_MODEL', 'llama3.2:3b'))
|
|
174
|
+
if env['OPENAI_API_KEY']
|
|
175
|
+
config.add_provider(
|
|
176
|
+
:openai,
|
|
177
|
+
Prescient::Provider::OpenAI,
|
|
178
|
+
api_key: env['OPENAI_API_KEY'],
|
|
179
|
+
embedding_model: env.fetch('OPENAI_EMBEDDING_MODEL', 'text-embedding-3-small'),
|
|
180
|
+
chat_model: env.fetch('OPENAI_CHAT_MODEL', 'gpt-4.1-mini'),
|
|
181
|
+
)
|
|
182
|
+
end
|
|
183
|
+
if env['ANTHROPIC_API_KEY']
|
|
184
|
+
config.add_provider(
|
|
185
|
+
:anthropic,
|
|
186
|
+
Prescient::Provider::Anthropic,
|
|
187
|
+
api_key: env['ANTHROPIC_API_KEY'],
|
|
188
|
+
model: env.fetch('ANTHROPIC_MODEL', 'claude-sonnet-4-20250514'),
|
|
189
|
+
)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
return unless env['HUGGINGFACE_API_KEY']
|
|
193
|
+
|
|
194
|
+
config.add_provider(
|
|
195
|
+
:huggingface,
|
|
196
|
+
Prescient::Provider::HuggingFace,
|
|
197
|
+
api_key: env['HUGGINGFACE_API_KEY'],
|
|
198
|
+
embedding_model: env.fetch(
|
|
199
|
+
'HUGGINGFACE_EMBEDDING_MODEL',
|
|
200
|
+
'sentence-transformers/all-MiniLM-L6-v2',
|
|
201
|
+
),
|
|
202
|
+
chat_model: env.fetch(
|
|
203
|
+
'HUGGINGFACE_CHAT_MODEL',
|
|
204
|
+
'google/gemma-2-2b-it',
|
|
205
|
+
),
|
|
206
|
+
)
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
|
|
171
210
|
# Default configuration
|
|
172
211
|
configure do |config|
|
|
173
|
-
config
|
|
174
|
-
url: ENV.fetch('OLLAMA_URL', 'http://localhost:11434'),
|
|
175
|
-
embedding_model: ENV.fetch('OLLAMA_EMBEDDING_MODEL', 'nomic-embed-text'),
|
|
176
|
-
chat_model: ENV.fetch('OLLAMA_CHAT_MODEL', 'llama3.1:8b'))
|
|
177
|
-
|
|
178
|
-
config.add_provider(:anthropic, Prescient::Provider::Anthropic,
|
|
179
|
-
api_key: ENV.fetch('ANTHROPIC_API_KEY', nil),
|
|
180
|
-
model: ENV.fetch('ANTHROPIC_MODEL', 'claude-3-haiku-20240307'))
|
|
181
|
-
|
|
182
|
-
config.add_provider(:openai, Prescient::Provider::OpenAI,
|
|
183
|
-
api_key: ENV.fetch('OPENAI_API_KEY', nil),
|
|
184
|
-
embedding_model: ENV.fetch('OPENAI_EMBEDDING_MODEL', 'text-embedding-3-small'),
|
|
185
|
-
chat_model: ENV.fetch('OPENAI_CHAT_MODEL', 'gpt-3.5-turbo'))
|
|
186
|
-
|
|
187
|
-
config.add_provider(:huggingface, Prescient::Provider::HuggingFace,
|
|
188
|
-
api_key: ENV.fetch('HUGGINGFACE_API_KEY', nil),
|
|
189
|
-
embedding_model: ENV.fetch('HUGGINGFACE_EMBEDDING_MODEL', 'sentence-transformers/all-MiniLM-L6-v2'),
|
|
190
|
-
chat_model: ENV.fetch('HUGGINGFACE_CHAT_MODEL', 'microsoft/DialoGPT-medium'))
|
|
212
|
+
configure_default_providers(config, ENV)
|
|
191
213
|
end
|
|
192
214
|
end
|
|
@@ -5,7 +5,7 @@ set -e
|
|
|
5
5
|
|
|
6
6
|
OLLAMA_URL=${OLLAMA_URL:-"http://localhost:11434"}
|
|
7
7
|
EMBEDDING_MODEL=${OLLAMA_EMBEDDING_MODEL:-"nomic-embed-text"}
|
|
8
|
-
CHAT_MODEL=${OLLAMA_CHAT_MODEL:-"llama3.
|
|
8
|
+
CHAT_MODEL=${OLLAMA_CHAT_MODEL:-"llama3.2:3b"}
|
|
9
9
|
|
|
10
10
|
echo "🚀 Setting up Ollama models for Prescient gem..."
|
|
11
11
|
echo "Ollama URL: $OLLAMA_URL"
|
|
@@ -74,4 +74,4 @@ main() {
|
|
|
74
74
|
echo " OLLAMA_URL=$OLLAMA_URL ruby examples/custom_contexts.rb"
|
|
75
75
|
}
|
|
76
76
|
|
|
77
|
-
main "$@"
|
|
77
|
+
main "$@"
|