ollama-ruby 0.4.0 → 0.6.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.
data/bin/ollama_cli CHANGED
@@ -16,6 +16,8 @@ def usage
16
16
  -M OPTIONS the ollama model options to use, OLLAMA_MODEL_OPTIONS
17
17
  -s SYSTEM the system prompt to use as a file, OLLAMA_SYSTEM
18
18
  -p PROMPT the user prompt to use as a file, OLLAMA_PROMPT
19
+ if it contains %{stdin} it is substituted by stdin input
20
+ -P VARIABLE sets prompt var %{foo} to "bar" if VARIABLE is foo=bar
19
21
  -H HANDLER the handler to use for the response, defaults to Print
20
22
  -S use streaming for generation
21
23
  -h this help
@@ -24,7 +26,7 @@ def usage
24
26
  exit 0
25
27
  end
26
28
 
27
- opts = go 'u:m:M:s:p:H:Sh', defaults: { ?H => 'Print', ?M => '{}' }
29
+ opts = go 'u:m:M:s:p:P:H:Sh', defaults: { ?H => 'Print', ?M => '{}' }
28
30
 
29
31
  opts[?h] and usage
30
32
 
@@ -38,14 +40,14 @@ prompt = get_file_argument(opts[?p], default: ENV['OLLAMA_PROMPT'])
38
40
 
39
41
  if prompt.nil?
40
42
  prompt = STDIN.read
41
- elsif c = prompt.scan('%s').size
42
- case c
43
- when 0
44
- when 1
45
- prompt = prompt % STDIN.read
46
- else
47
- STDERR.puts "Found more than one plaeceholder %s. => Ignoring."
48
- end
43
+ else
44
+ vars = prompt.scan(/%\{([^}]+)\}/).inject([], &:concat).uniq.map(&:to_sym)
45
+ stdin = (STDIN.read if vars.include?(:stdin)).to_s
46
+ values = opts[?P].to_a.inject({ stdin: }) { |h, pair|
47
+ n, v = pair.split(?=, 2)
48
+ h.merge(n.to_sym => v)
49
+ }
50
+ prompt = prompt % values
49
51
  end
50
52
 
51
53
  if ENV['DEBUG'].to_i == 1
data/docker-compose.yml CHANGED
@@ -2,10 +2,9 @@ services:
2
2
  redis:
3
3
  image: redis:7.2.5-alpine
4
4
  restart: unless-stopped
5
- ports:
6
- - "9736:6379"
5
+ ports: [ "127.0.0.1:9736:6379" ]
7
6
  volumes:
8
- - "redis-data:/data:delegated"
9
- - "./config/redis.conf:/etc/redis.conf"
7
+ - "redis-data:/data:delegated"
8
+ - "./config/redis.conf:/etc/redis.conf"
10
9
  volumes:
11
10
  redis-data:
data/lib/ollama/client.rb CHANGED
@@ -19,8 +19,8 @@ class Ollama::Client
19
19
  'missing :base_url parameter or OLLAMA_URL environment variable'
20
20
  end
21
21
  base_url.is_a? URI or base_url = URI.parse(base_url)
22
- base_url.is_a?(URI::HTTP) || base_url.is_a?(URI::HTTPS) or
23
- raise ArgumentError, "require #{base_url.inspect} to be http/https-URI"
22
+ base_url.is_a?(URI::HTTP) || base_url.is_a?(URI::HTTPS) or
23
+ raise ArgumentError, "require #{base_url.inspect} to be http/https-URI"
24
24
  @ssl_verify_peer = base_url.query.to_s.split(?&).inject({}) { |h, l|
25
25
  h.merge Hash[*l.split(?=)]
26
26
  }['ssl_verify_peer'] != 'false'
@@ -2,16 +2,18 @@ require 'redis'
2
2
 
3
3
  class Ollama::Documents
4
4
  class RedisBackedMemoryCache < MemoryCache
5
- def initialize(prefix:, url: ENV['REDIS_URL'])
5
+ def initialize(prefix:, url: ENV['REDIS_URL'], object_class: nil)
6
6
  super(prefix:)
7
7
  url or raise ArgumentError, 'require redis url'
8
- @prefix, @url = prefix, url
9
- @redis_cache = Ollama::Documents::RedisCache.new(prefix:, url:)
8
+ @prefix, @url, @object_class = prefix, url, object_class
9
+ @redis_cache = Ollama::Documents::RedisCache.new(prefix:, url:, object_class:)
10
10
  @redis_cache.full_each do |key, value|
11
11
  @data[key] = value
12
12
  end
13
13
  end
14
14
 
15
+ attr_reader :object_class
16
+
15
17
  def redis
16
18
  @redis_cache.redis
17
19
  end
@@ -32,13 +34,5 @@ class Ollama::Documents
32
34
  super
33
35
  self
34
36
  end
35
-
36
- def pre(key)
37
- [ @prefix, key ].join
38
- end
39
-
40
- def unpre(key)
41
- key.sub(/\A#@prefix/, '')
42
- end
43
37
  end
44
38
  end
@@ -4,11 +4,13 @@ require 'redis'
4
4
  class Ollama::Documents::RedisCache
5
5
  include Ollama::Documents::Cache::Common
6
6
 
7
- def initialize(prefix:, url: ENV['REDIS_URL'])
7
+ def initialize(prefix:, url: ENV['REDIS_URL'], object_class: nil, ex: nil)
8
8
  url or raise ArgumentError, 'require redis url'
9
- @prefix, @url = prefix, url
9
+ @prefix, @url, @object_class, @ex = prefix, url, object_class, ex
10
10
  end
11
11
 
12
+ attr_reader :object_class
13
+
12
14
  def redis
13
15
  @redis ||= Redis.new(url: @url)
14
16
  end
@@ -16,12 +18,16 @@ class Ollama::Documents::RedisCache
16
18
  def [](key)
17
19
  value = redis.get(pre(key))
18
20
  unless value.nil?
19
- JSON(value, object_class: Ollama::Documents::Record)
21
+ JSON(value, object_class:)
20
22
  end
21
23
  end
22
24
 
23
25
  def []=(key, value)
24
- redis.set(pre(key), JSON(value))
26
+ redis.set(pre(key), JSON.generate(value), ex: @ex)
27
+ end
28
+
29
+ def ttl(key)
30
+ redis.ttl(pre(key))
25
31
  end
26
32
 
27
33
  def key?(key)
@@ -50,7 +56,7 @@ class Ollama::Documents::RedisCache
50
56
  include Enumerable
51
57
 
52
58
  def full_each(&block)
53
- redis.scan_each do |key|
59
+ redis.scan_each(match: [ Ollama::Documents, ?* ] * ?-) do |key|
54
60
  value = redis.get(key) or next
55
61
  value = JSON(value, object_class: Ollama::Documents::Record)
56
62
  block.(key, value)
@@ -2,8 +2,9 @@ module Ollama::Documents::Splitters
2
2
  class Character
3
3
  DEFAULT_SEPARATOR = /(?:\r?\n){2,}/
4
4
 
5
- def initialize(separator: DEFAULT_SEPARATOR, include_separator: false, chunk_size: 4096)
6
- @separator, @include_separator, @chunk_size = separator, include_separator, chunk_size
5
+ def initialize(separator: DEFAULT_SEPARATOR, include_separator: false, combining_string: "\n\n", chunk_size: 4096)
6
+ @separator, @include_separator, @combining_string, @chunk_size =
7
+ separator, include_separator, combining_string, chunk_size
7
8
  if include_separator
8
9
  @separator = Regexp.new("(#@separator)")
9
10
  end
@@ -22,7 +23,7 @@ module Ollama::Documents::Splitters
22
23
  current_text = +''
23
24
  texts.each do |t|
24
25
  if current_text.size + t.size < @chunk_size
25
- current_text += t
26
+ current_text << t << @combining_string
26
27
  else
27
28
  current_text.empty? or result << current_text
28
29
  current_text = t
@@ -41,11 +42,11 @@ module Ollama::Documents::Splitters
41
42
  //,
42
43
  ].freeze
43
44
 
44
- def initialize(separators: DEFAULT_SEPARATORS, include_separator: false, chunk_size: 4096)
45
+ def initialize(separators: DEFAULT_SEPARATORS, include_separator: false, combining_string: "\n\n", chunk_size: 4096)
45
46
  separators.empty? and
46
47
  raise ArgumentError, "non-empty array of separators required"
47
- @separators, @include_separator, @chunk_size =
48
- separators, include_separator, chunk_size
48
+ @separators, @include_separator, @combining_string, @chunk_size =
49
+ separators, include_separator, combining_string, chunk_size
49
50
  end
50
51
 
51
52
  def split(text, separators: @separators)
@@ -55,6 +56,7 @@ module Ollama::Documents::Splitters
55
56
  texts = Character.new(
56
57
  separator:,
57
58
  include_separator: @include_separator,
59
+ combining_string: @combining_string,
58
60
  chunk_size: @chunk_size
59
61
  ).split(text)
60
62
  texts.count == 0 and return [ text ]
@@ -12,7 +12,7 @@ module Ollama::Documents::Splitters
12
12
  def split(text, batch_size: 100, breakpoint: :percentile, **opts)
13
13
  sentences = Ollama::Documents::Splitters::Character.new(
14
14
  separator: @separator,
15
- include_separator: true,
15
+ include_separator: opts.fetch(:include_separator, true),
16
16
  chunk_size: 1,
17
17
  ).split(text)
18
18
  embeddings = sentences.with_infobar(label: 'Split').each_slice(batch_size).inject([]) do |e, batch|
@@ -35,16 +35,20 @@ class Ollama::Documents
35
35
  alias inspect to_s
36
36
  end
37
37
 
38
- def initialize(ollama:, model:, model_options: nil, collection: default_collection, cache: MemoryCache, redis_url: nil)
39
- @ollama, @model, @model_options, @collection = ollama, model, model_options, collection.to_sym
40
- @cache, @redis_url = connect_cache(cache), redis_url
38
+ def initialize(ollama:, model:, model_options: nil, collection: nil, cache: MemoryCache, redis_url: nil, debug: false)
39
+ collection ||= default_collection
40
+ @ollama, @model, @model_options, @collection =
41
+ ollama, model, model_options, collection.to_sym
42
+ @redis_url = redis_url
43
+ @cache = connect_cache(cache)
44
+ @debug = debug
41
45
  end
42
46
 
43
47
  def default_collection
44
48
  :default
45
49
  end
46
50
 
47
- attr_reader :ollama, :model, :collection
51
+ attr_reader :ollama, :model, :collection, :cache
48
52
 
49
53
  def collection=(new_collection)
50
54
  @collection = new_collection.to_sym
@@ -61,6 +65,9 @@ class Ollama::Documents
61
65
  }
62
66
  inputs.reject! { |i| exist?(i) }
63
67
  inputs.empty? and return self
68
+ if @debug
69
+ puts Ollama::Utils::ColorizeTexts.new(inputs)
70
+ end
64
71
  batches = inputs.each_slice(batch_size).
65
72
  with_infobar(
66
73
  label: "Add #{truncate(tags.to_s, percentage: 25)}",
@@ -161,7 +168,7 @@ class Ollama::Documents
161
168
  cache = nil
162
169
  if cache_class.instance_method(:redis)
163
170
  begin
164
- cache = cache_class.new(prefix:)
171
+ cache = cache_class.new(prefix:, url: @redis_url, object_class: Record)
165
172
  cache.size
166
173
  rescue Redis::CannotConnectError
167
174
  STDERR.puts(
@@ -0,0 +1,38 @@
1
+ require 'digest/md5'
2
+
3
+ class Ollama::Utils::CacheFetcher
4
+ def initialize(cache)
5
+ @cache = cache
6
+ end
7
+
8
+ def get(url, &block)
9
+ block or raise ArgumentError, 'require block argument'
10
+ body = @cache[key(:body, url)]
11
+ content_type = @cache[key(:content_type, url)]
12
+ content_type = MIME::Types[content_type].first
13
+ if body && content_type
14
+ io = StringIO.new(body)
15
+ io.rewind
16
+ io.extend(Ollama::Utils::Fetcher::ContentType)
17
+ io.content_type = content_type
18
+ block.(io)
19
+ end
20
+ end
21
+
22
+ def put(url, io)
23
+ io.rewind
24
+ body = io.read
25
+ body.empty? and return
26
+ content_type = io.content_type
27
+ content_type.nil? and return
28
+ @cache[key(:body, url)] = body
29
+ @cache[key(:content_type, url)] = content_type.to_s
30
+ self
31
+ end
32
+
33
+ private
34
+
35
+ def key(type, url)
36
+ [ type, Digest::MD5.hexdigest(url) ] * ?-
37
+ end
38
+ end
@@ -3,22 +3,80 @@ require 'tins/unit'
3
3
  require 'infobar'
4
4
  require 'mime-types'
5
5
  require 'stringio'
6
+ require 'ollama/utils/cache_fetcher'
6
7
 
7
8
  class Ollama::Utils::Fetcher
8
9
  module ContentType
9
10
  attr_accessor :content_type
11
+
12
+ def self.failed
13
+ object = StringIO.new.extend(self)
14
+ object.content_type = MIME::Types['text/plain'].first
15
+ object
16
+ end
10
17
  end
11
18
 
12
19
  class RetryWithoutStreaming < StandardError; end
13
20
 
14
- def initialize(debug: false)
15
- @debug = debug
16
- @started = false
17
- @streaming = true
21
+ def self.get(url, **options, &block)
22
+ cache = options.delete(:cache) and
23
+ cache = Ollama::Utils::CacheFetcher.new(cache)
24
+ if result = cache&.get(url, &block)
25
+ infobar.puts "Getting #{url.inspect} from cache."
26
+ return result
27
+ else
28
+ new(**options).send(:get, url) do |tmp|
29
+ result = block.(tmp)
30
+ if cache && !tmp.is_a?(StringIO)
31
+ tmp.rewind
32
+ cache.put(url, tmp)
33
+ end
34
+ result
35
+ end
36
+ end
18
37
  end
19
38
 
20
- def self.get(url, **options, &block)
21
- new(**options).get(url, &block)
39
+ def self.read(filename, &block)
40
+ if File.exist?(filename)
41
+ File.open(filename) do |file|
42
+ file.extend(Ollama::Utils::Fetcher::ContentType)
43
+ file.content_type = MIME::Types.type_for(filename).first
44
+ block.(file)
45
+ end
46
+ end
47
+ end
48
+
49
+ def self.execute(command, &block)
50
+ Tempfile.open do |tmp|
51
+ IO.popen(command) do |command|
52
+ until command.eof?
53
+ tmp.write command.read(4096)
54
+ end
55
+ tmp.rewind
56
+ tmp.extend(Ollama::Utils::Fetcher::ContentType)
57
+ tmp.content_type = MIME::Types['text/plain'].first
58
+ block.(tmp)
59
+ end
60
+ end
61
+ rescue => e
62
+ STDERR.puts "Cannot execute #{command.inspect} (#{e})"
63
+ if @debug && !e.is_a?(RuntimeError)
64
+ STDERR.puts "#{e.backtrace * ?\n}"
65
+ end
66
+ yield ContentType.failed
67
+ end
68
+
69
+ def initialize(debug: false, http_options: {})
70
+ @debug = debug
71
+ @started = false
72
+ @streaming = true
73
+ @http_options = http_options
74
+ end
75
+
76
+ private
77
+
78
+ def excon(url, **options)
79
+ Excon.new(url, options.merge(@http_options))
22
80
  end
23
81
 
24
82
  def get(url, &block)
@@ -26,13 +84,13 @@ class Ollama::Utils::Fetcher
26
84
  Tempfile.open do |tmp|
27
85
  infobar.label = 'Getting'
28
86
  if @streaming
29
- response = Excon.get(url, headers:, response_block: callback(tmp))
87
+ response = excon(url, headers:, response_block: callback(tmp)).request(method: :get)
30
88
  response.status != 200 || !@started and raise RetryWithoutStreaming
31
89
  decorate_io(tmp, response)
32
90
  infobar.finish
33
91
  block.(tmp)
34
92
  else
35
- response = Excon.get(url, headers:, middlewares:)
93
+ response = excon(url, headers:, middlewares:).request(method: :get)
36
94
  if response.status != 200
37
95
  raise "invalid response status code"
38
96
  end
@@ -52,7 +110,7 @@ class Ollama::Utils::Fetcher
52
110
  if @debug && !e.is_a?(RuntimeError)
53
111
  STDERR.puts "#{e.backtrace * ?\n}"
54
112
  end
55
- yield StringIO.new.extend(ContentType)
113
+ yield ContentType.failed
56
114
  end
57
115
 
58
116
  def headers
@@ -94,14 +152,4 @@ class Ollama::Utils::Fetcher
94
152
  }
95
153
  '%l ' + progress + ' in %te, ETA %e @%E'
96
154
  end
97
-
98
- def self.read(filename, &block)
99
- if File.exist?(filename)
100
- File.open(filename) do |file|
101
- file.extend(Ollama::Utils::Fetcher::ContentType)
102
- file.content_type = MIME::Types.type_for(filename).first
103
- block.(file)
104
- end
105
- end
106
- end
107
155
  end
@@ -23,7 +23,7 @@ module Ollama::Utils::FileArgument
23
23
  if path_or_content.present? && path_or_content.size < 2 ** 15 &&
24
24
  File.basename(path_or_content).size < 2 ** 8 &&
25
25
  File.exist?(path_or_content)
26
- then
26
+ then
27
27
  File.read(path_or_content)
28
28
  elsif path_or_content.present?
29
29
  path_or_content
@@ -1,6 +1,6 @@
1
1
  module Ollama
2
2
  # Ollama version
3
- VERSION = '0.4.0'
3
+ VERSION = '0.6.0'
4
4
  VERSION_ARRAY = VERSION.split('.').map(&:to_i) # :nodoc:
5
5
  VERSION_MAJOR = VERSION_ARRAY[0] # :nodoc:
6
6
  VERSION_MINOR = VERSION_ARRAY[1] # :nodoc:
data/lib/ollama.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require 'json'
2
+ require 'logger'
2
3
  require 'excon'
3
4
 
4
5
  module Ollama
data/ollama-ruby.gemspec CHANGED
@@ -1,30 +1,30 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: ollama-ruby 0.4.0 ruby lib
2
+ # stub: ollama-ruby 0.6.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ollama-ruby".freeze
6
- s.version = "0.4.0".freeze
6
+ s.version = "0.6.0".freeze
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib".freeze]
10
10
  s.authors = ["Florian Frank".freeze]
11
- s.date = "2024-09-21"
11
+ s.date = "2024-09-30"
12
12
  s.description = "Library that allows interacting with the Ollama API".freeze
13
13
  s.email = "flori@ping.de".freeze
14
14
  s.executables = ["ollama_console".freeze, "ollama_chat".freeze, "ollama_update".freeze, "ollama_cli".freeze]
15
- s.extra_rdoc_files = ["README.md".freeze, "lib/ollama.rb".freeze, "lib/ollama/client.rb".freeze, "lib/ollama/client/command.rb".freeze, "lib/ollama/client/doc.rb".freeze, "lib/ollama/commands/chat.rb".freeze, "lib/ollama/commands/copy.rb".freeze, "lib/ollama/commands/create.rb".freeze, "lib/ollama/commands/delete.rb".freeze, "lib/ollama/commands/embed.rb".freeze, "lib/ollama/commands/embeddings.rb".freeze, "lib/ollama/commands/generate.rb".freeze, "lib/ollama/commands/ps.rb".freeze, "lib/ollama/commands/pull.rb".freeze, "lib/ollama/commands/push.rb".freeze, "lib/ollama/commands/show.rb".freeze, "lib/ollama/commands/tags.rb".freeze, "lib/ollama/documents.rb".freeze, "lib/ollama/documents/cache/common.rb".freeze, "lib/ollama/documents/cache/memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_backed_memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_cache.rb".freeze, "lib/ollama/documents/splitters/character.rb".freeze, "lib/ollama/documents/splitters/semantic.rb".freeze, "lib/ollama/dto.rb".freeze, "lib/ollama/errors.rb".freeze, "lib/ollama/handlers.rb".freeze, "lib/ollama/handlers/collector.rb".freeze, "lib/ollama/handlers/concern.rb".freeze, "lib/ollama/handlers/dump_json.rb".freeze, "lib/ollama/handlers/dump_yaml.rb".freeze, "lib/ollama/handlers/markdown.rb".freeze, "lib/ollama/handlers/nop.rb".freeze, "lib/ollama/handlers/print.rb".freeze, "lib/ollama/handlers/progress.rb".freeze, "lib/ollama/handlers/say.rb".freeze, "lib/ollama/handlers/single.rb".freeze, "lib/ollama/image.rb".freeze, "lib/ollama/message.rb".freeze, "lib/ollama/options.rb".freeze, "lib/ollama/response.rb".freeze, "lib/ollama/tool.rb".freeze, "lib/ollama/tool/function.rb".freeze, "lib/ollama/tool/function/parameters.rb".freeze, "lib/ollama/tool/function/parameters/property.rb".freeze, "lib/ollama/utils/ansi_markdown.rb".freeze, "lib/ollama/utils/chooser.rb".freeze, "lib/ollama/utils/colorize_texts.rb".freeze, "lib/ollama/utils/fetcher.rb".freeze, "lib/ollama/utils/file_argument.rb".freeze, "lib/ollama/utils/math.rb".freeze, "lib/ollama/utils/tags.rb".freeze, "lib/ollama/utils/width.rb".freeze, "lib/ollama/version.rb".freeze]
16
- s.files = [".envrc".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/ollama_chat".freeze, "bin/ollama_cli".freeze, "bin/ollama_console".freeze, "bin/ollama_update".freeze, "config/redis.conf".freeze, "docker-compose.yml".freeze, "lib/ollama.rb".freeze, "lib/ollama/client.rb".freeze, "lib/ollama/client/command.rb".freeze, "lib/ollama/client/doc.rb".freeze, "lib/ollama/commands/chat.rb".freeze, "lib/ollama/commands/copy.rb".freeze, "lib/ollama/commands/create.rb".freeze, "lib/ollama/commands/delete.rb".freeze, "lib/ollama/commands/embed.rb".freeze, "lib/ollama/commands/embeddings.rb".freeze, "lib/ollama/commands/generate.rb".freeze, "lib/ollama/commands/ps.rb".freeze, "lib/ollama/commands/pull.rb".freeze, "lib/ollama/commands/push.rb".freeze, "lib/ollama/commands/show.rb".freeze, "lib/ollama/commands/tags.rb".freeze, "lib/ollama/documents.rb".freeze, "lib/ollama/documents/cache/common.rb".freeze, "lib/ollama/documents/cache/memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_backed_memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_cache.rb".freeze, "lib/ollama/documents/splitters/character.rb".freeze, "lib/ollama/documents/splitters/semantic.rb".freeze, "lib/ollama/dto.rb".freeze, "lib/ollama/errors.rb".freeze, "lib/ollama/handlers.rb".freeze, "lib/ollama/handlers/collector.rb".freeze, "lib/ollama/handlers/concern.rb".freeze, "lib/ollama/handlers/dump_json.rb".freeze, "lib/ollama/handlers/dump_yaml.rb".freeze, "lib/ollama/handlers/markdown.rb".freeze, "lib/ollama/handlers/nop.rb".freeze, "lib/ollama/handlers/print.rb".freeze, "lib/ollama/handlers/progress.rb".freeze, "lib/ollama/handlers/say.rb".freeze, "lib/ollama/handlers/single.rb".freeze, "lib/ollama/image.rb".freeze, "lib/ollama/message.rb".freeze, "lib/ollama/options.rb".freeze, "lib/ollama/response.rb".freeze, "lib/ollama/tool.rb".freeze, "lib/ollama/tool/function.rb".freeze, "lib/ollama/tool/function/parameters.rb".freeze, "lib/ollama/tool/function/parameters/property.rb".freeze, "lib/ollama/utils/ansi_markdown.rb".freeze, "lib/ollama/utils/chooser.rb".freeze, "lib/ollama/utils/colorize_texts.rb".freeze, "lib/ollama/utils/fetcher.rb".freeze, "lib/ollama/utils/file_argument.rb".freeze, "lib/ollama/utils/math.rb".freeze, "lib/ollama/utils/tags.rb".freeze, "lib/ollama/utils/width.rb".freeze, "lib/ollama/version.rb".freeze, "ollama-ruby.gemspec".freeze, "spec/assets/embeddings.json".freeze, "spec/assets/kitten.jpg".freeze, "spec/assets/prompt.txt".freeze, "spec/ollama/client/doc_spec.rb".freeze, "spec/ollama/client_spec.rb".freeze, "spec/ollama/commands/chat_spec.rb".freeze, "spec/ollama/commands/copy_spec.rb".freeze, "spec/ollama/commands/create_spec.rb".freeze, "spec/ollama/commands/delete_spec.rb".freeze, "spec/ollama/commands/embed_spec.rb".freeze, "spec/ollama/commands/embeddings_spec.rb".freeze, "spec/ollama/commands/generate_spec.rb".freeze, "spec/ollama/commands/ps_spec.rb".freeze, "spec/ollama/commands/pull_spec.rb".freeze, "spec/ollama/commands/push_spec.rb".freeze, "spec/ollama/commands/show_spec.rb".freeze, "spec/ollama/commands/tags_spec.rb".freeze, "spec/ollama/documents/memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_backed_memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_cache_spec.rb".freeze, "spec/ollama/documents/splitters/character_spec.rb".freeze, "spec/ollama/documents/splitters/semantic_spec.rb".freeze, "spec/ollama/documents_spec.rb".freeze, "spec/ollama/handlers/collector_spec.rb".freeze, "spec/ollama/handlers/dump_json_spec.rb".freeze, "spec/ollama/handlers/dump_yaml_spec.rb".freeze, "spec/ollama/handlers/markdown_spec.rb".freeze, "spec/ollama/handlers/nop_spec.rb".freeze, "spec/ollama/handlers/print_spec.rb".freeze, "spec/ollama/handlers/progress_spec.rb".freeze, "spec/ollama/handlers/say_spec.rb".freeze, "spec/ollama/handlers/single_spec.rb".freeze, "spec/ollama/image_spec.rb".freeze, "spec/ollama/message_spec.rb".freeze, "spec/ollama/options_spec.rb".freeze, "spec/ollama/tool_spec.rb".freeze, "spec/ollama/utils/ansi_markdown_spec.rb".freeze, "spec/ollama/utils/fetcher_spec.rb".freeze, "spec/ollama/utils/file_argument_spec.rb".freeze, "spec/ollama/utils/tags_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tmp/.keep".freeze]
15
+ s.extra_rdoc_files = ["README.md".freeze, "lib/ollama.rb".freeze, "lib/ollama/client.rb".freeze, "lib/ollama/client/command.rb".freeze, "lib/ollama/client/doc.rb".freeze, "lib/ollama/commands/chat.rb".freeze, "lib/ollama/commands/copy.rb".freeze, "lib/ollama/commands/create.rb".freeze, "lib/ollama/commands/delete.rb".freeze, "lib/ollama/commands/embed.rb".freeze, "lib/ollama/commands/embeddings.rb".freeze, "lib/ollama/commands/generate.rb".freeze, "lib/ollama/commands/ps.rb".freeze, "lib/ollama/commands/pull.rb".freeze, "lib/ollama/commands/push.rb".freeze, "lib/ollama/commands/show.rb".freeze, "lib/ollama/commands/tags.rb".freeze, "lib/ollama/documents.rb".freeze, "lib/ollama/documents/cache/common.rb".freeze, "lib/ollama/documents/cache/memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_backed_memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_cache.rb".freeze, "lib/ollama/documents/splitters/character.rb".freeze, "lib/ollama/documents/splitters/semantic.rb".freeze, "lib/ollama/dto.rb".freeze, "lib/ollama/errors.rb".freeze, "lib/ollama/handlers.rb".freeze, "lib/ollama/handlers/collector.rb".freeze, "lib/ollama/handlers/concern.rb".freeze, "lib/ollama/handlers/dump_json.rb".freeze, "lib/ollama/handlers/dump_yaml.rb".freeze, "lib/ollama/handlers/markdown.rb".freeze, "lib/ollama/handlers/nop.rb".freeze, "lib/ollama/handlers/print.rb".freeze, "lib/ollama/handlers/progress.rb".freeze, "lib/ollama/handlers/say.rb".freeze, "lib/ollama/handlers/single.rb".freeze, "lib/ollama/image.rb".freeze, "lib/ollama/message.rb".freeze, "lib/ollama/options.rb".freeze, "lib/ollama/response.rb".freeze, "lib/ollama/tool.rb".freeze, "lib/ollama/tool/function.rb".freeze, "lib/ollama/tool/function/parameters.rb".freeze, "lib/ollama/tool/function/parameters/property.rb".freeze, "lib/ollama/utils/ansi_markdown.rb".freeze, "lib/ollama/utils/cache_fetcher.rb".freeze, "lib/ollama/utils/chooser.rb".freeze, "lib/ollama/utils/colorize_texts.rb".freeze, "lib/ollama/utils/fetcher.rb".freeze, "lib/ollama/utils/file_argument.rb".freeze, "lib/ollama/utils/math.rb".freeze, "lib/ollama/utils/tags.rb".freeze, "lib/ollama/utils/width.rb".freeze, "lib/ollama/version.rb".freeze]
16
+ s.files = [".envrc".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "LICENSE".freeze, "README.md".freeze, "Rakefile".freeze, "bin/ollama_chat".freeze, "bin/ollama_cli".freeze, "bin/ollama_console".freeze, "bin/ollama_update".freeze, "config/redis.conf".freeze, "docker-compose.yml".freeze, "lib/ollama.rb".freeze, "lib/ollama/client.rb".freeze, "lib/ollama/client/command.rb".freeze, "lib/ollama/client/doc.rb".freeze, "lib/ollama/commands/chat.rb".freeze, "lib/ollama/commands/copy.rb".freeze, "lib/ollama/commands/create.rb".freeze, "lib/ollama/commands/delete.rb".freeze, "lib/ollama/commands/embed.rb".freeze, "lib/ollama/commands/embeddings.rb".freeze, "lib/ollama/commands/generate.rb".freeze, "lib/ollama/commands/ps.rb".freeze, "lib/ollama/commands/pull.rb".freeze, "lib/ollama/commands/push.rb".freeze, "lib/ollama/commands/show.rb".freeze, "lib/ollama/commands/tags.rb".freeze, "lib/ollama/documents.rb".freeze, "lib/ollama/documents/cache/common.rb".freeze, "lib/ollama/documents/cache/memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_backed_memory_cache.rb".freeze, "lib/ollama/documents/cache/redis_cache.rb".freeze, "lib/ollama/documents/splitters/character.rb".freeze, "lib/ollama/documents/splitters/semantic.rb".freeze, "lib/ollama/dto.rb".freeze, "lib/ollama/errors.rb".freeze, "lib/ollama/handlers.rb".freeze, "lib/ollama/handlers/collector.rb".freeze, "lib/ollama/handlers/concern.rb".freeze, "lib/ollama/handlers/dump_json.rb".freeze, "lib/ollama/handlers/dump_yaml.rb".freeze, "lib/ollama/handlers/markdown.rb".freeze, "lib/ollama/handlers/nop.rb".freeze, "lib/ollama/handlers/print.rb".freeze, "lib/ollama/handlers/progress.rb".freeze, "lib/ollama/handlers/say.rb".freeze, "lib/ollama/handlers/single.rb".freeze, "lib/ollama/image.rb".freeze, "lib/ollama/message.rb".freeze, "lib/ollama/options.rb".freeze, "lib/ollama/response.rb".freeze, "lib/ollama/tool.rb".freeze, "lib/ollama/tool/function.rb".freeze, "lib/ollama/tool/function/parameters.rb".freeze, "lib/ollama/tool/function/parameters/property.rb".freeze, "lib/ollama/utils/ansi_markdown.rb".freeze, "lib/ollama/utils/cache_fetcher.rb".freeze, "lib/ollama/utils/chooser.rb".freeze, "lib/ollama/utils/colorize_texts.rb".freeze, "lib/ollama/utils/fetcher.rb".freeze, "lib/ollama/utils/file_argument.rb".freeze, "lib/ollama/utils/math.rb".freeze, "lib/ollama/utils/tags.rb".freeze, "lib/ollama/utils/width.rb".freeze, "lib/ollama/version.rb".freeze, "ollama-ruby.gemspec".freeze, "spec/assets/embeddings.json".freeze, "spec/assets/kitten.jpg".freeze, "spec/assets/prompt.txt".freeze, "spec/ollama/client/doc_spec.rb".freeze, "spec/ollama/client_spec.rb".freeze, "spec/ollama/commands/chat_spec.rb".freeze, "spec/ollama/commands/copy_spec.rb".freeze, "spec/ollama/commands/create_spec.rb".freeze, "spec/ollama/commands/delete_spec.rb".freeze, "spec/ollama/commands/embed_spec.rb".freeze, "spec/ollama/commands/embeddings_spec.rb".freeze, "spec/ollama/commands/generate_spec.rb".freeze, "spec/ollama/commands/ps_spec.rb".freeze, "spec/ollama/commands/pull_spec.rb".freeze, "spec/ollama/commands/push_spec.rb".freeze, "spec/ollama/commands/show_spec.rb".freeze, "spec/ollama/commands/tags_spec.rb".freeze, "spec/ollama/documents/memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_backed_memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_cache_spec.rb".freeze, "spec/ollama/documents/splitters/character_spec.rb".freeze, "spec/ollama/documents/splitters/semantic_spec.rb".freeze, "spec/ollama/documents_spec.rb".freeze, "spec/ollama/handlers/collector_spec.rb".freeze, "spec/ollama/handlers/dump_json_spec.rb".freeze, "spec/ollama/handlers/dump_yaml_spec.rb".freeze, "spec/ollama/handlers/markdown_spec.rb".freeze, "spec/ollama/handlers/nop_spec.rb".freeze, "spec/ollama/handlers/print_spec.rb".freeze, "spec/ollama/handlers/progress_spec.rb".freeze, "spec/ollama/handlers/say_spec.rb".freeze, "spec/ollama/handlers/single_spec.rb".freeze, "spec/ollama/image_spec.rb".freeze, "spec/ollama/message_spec.rb".freeze, "spec/ollama/options_spec.rb".freeze, "spec/ollama/tool_spec.rb".freeze, "spec/ollama/utils/ansi_markdown_spec.rb".freeze, "spec/ollama/utils/cache_fetcher_spec.rb".freeze, "spec/ollama/utils/fetcher_spec.rb".freeze, "spec/ollama/utils/file_argument_spec.rb".freeze, "spec/ollama/utils/tags_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tmp/.keep".freeze]
17
17
  s.homepage = "https://github.com/flori/ollama-ruby".freeze
18
18
  s.licenses = ["MIT".freeze]
19
19
  s.rdoc_options = ["--title".freeze, "Ollama-ruby - Interacting with the Ollama API".freeze, "--main".freeze, "README.md".freeze]
20
20
  s.required_ruby_version = Gem::Requirement.new("~> 3.1".freeze)
21
21
  s.rubygems_version = "3.5.18".freeze
22
22
  s.summary = "Interacting with the Ollama API".freeze
23
- s.test_files = ["spec/ollama/client/doc_spec.rb".freeze, "spec/ollama/client_spec.rb".freeze, "spec/ollama/commands/chat_spec.rb".freeze, "spec/ollama/commands/copy_spec.rb".freeze, "spec/ollama/commands/create_spec.rb".freeze, "spec/ollama/commands/delete_spec.rb".freeze, "spec/ollama/commands/embed_spec.rb".freeze, "spec/ollama/commands/embeddings_spec.rb".freeze, "spec/ollama/commands/generate_spec.rb".freeze, "spec/ollama/commands/ps_spec.rb".freeze, "spec/ollama/commands/pull_spec.rb".freeze, "spec/ollama/commands/push_spec.rb".freeze, "spec/ollama/commands/show_spec.rb".freeze, "spec/ollama/commands/tags_spec.rb".freeze, "spec/ollama/documents/memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_backed_memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_cache_spec.rb".freeze, "spec/ollama/documents/splitters/character_spec.rb".freeze, "spec/ollama/documents/splitters/semantic_spec.rb".freeze, "spec/ollama/documents_spec.rb".freeze, "spec/ollama/handlers/collector_spec.rb".freeze, "spec/ollama/handlers/dump_json_spec.rb".freeze, "spec/ollama/handlers/dump_yaml_spec.rb".freeze, "spec/ollama/handlers/markdown_spec.rb".freeze, "spec/ollama/handlers/nop_spec.rb".freeze, "spec/ollama/handlers/print_spec.rb".freeze, "spec/ollama/handlers/progress_spec.rb".freeze, "spec/ollama/handlers/say_spec.rb".freeze, "spec/ollama/handlers/single_spec.rb".freeze, "spec/ollama/image_spec.rb".freeze, "spec/ollama/message_spec.rb".freeze, "spec/ollama/options_spec.rb".freeze, "spec/ollama/tool_spec.rb".freeze, "spec/ollama/utils/ansi_markdown_spec.rb".freeze, "spec/ollama/utils/fetcher_spec.rb".freeze, "spec/ollama/utils/file_argument_spec.rb".freeze, "spec/ollama/utils/tags_spec.rb".freeze, "spec/spec_helper.rb".freeze]
23
+ s.test_files = ["spec/ollama/client/doc_spec.rb".freeze, "spec/ollama/client_spec.rb".freeze, "spec/ollama/commands/chat_spec.rb".freeze, "spec/ollama/commands/copy_spec.rb".freeze, "spec/ollama/commands/create_spec.rb".freeze, "spec/ollama/commands/delete_spec.rb".freeze, "spec/ollama/commands/embed_spec.rb".freeze, "spec/ollama/commands/embeddings_spec.rb".freeze, "spec/ollama/commands/generate_spec.rb".freeze, "spec/ollama/commands/ps_spec.rb".freeze, "spec/ollama/commands/pull_spec.rb".freeze, "spec/ollama/commands/push_spec.rb".freeze, "spec/ollama/commands/show_spec.rb".freeze, "spec/ollama/commands/tags_spec.rb".freeze, "spec/ollama/documents/memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_backed_memory_cache_spec.rb".freeze, "spec/ollama/documents/redis_cache_spec.rb".freeze, "spec/ollama/documents/splitters/character_spec.rb".freeze, "spec/ollama/documents/splitters/semantic_spec.rb".freeze, "spec/ollama/documents_spec.rb".freeze, "spec/ollama/handlers/collector_spec.rb".freeze, "spec/ollama/handlers/dump_json_spec.rb".freeze, "spec/ollama/handlers/dump_yaml_spec.rb".freeze, "spec/ollama/handlers/markdown_spec.rb".freeze, "spec/ollama/handlers/nop_spec.rb".freeze, "spec/ollama/handlers/print_spec.rb".freeze, "spec/ollama/handlers/progress_spec.rb".freeze, "spec/ollama/handlers/say_spec.rb".freeze, "spec/ollama/handlers/single_spec.rb".freeze, "spec/ollama/image_spec.rb".freeze, "spec/ollama/message_spec.rb".freeze, "spec/ollama/options_spec.rb".freeze, "spec/ollama/tool_spec.rb".freeze, "spec/ollama/utils/ansi_markdown_spec.rb".freeze, "spec/ollama/utils/cache_fetcher_spec.rb".freeze, "spec/ollama/utils/fetcher_spec.rb".freeze, "spec/ollama/utils/file_argument_spec.rb".freeze, "spec/ollama/utils/tags_spec.rb".freeze, "spec/spec_helper.rb".freeze]
24
24
 
25
25
  s.specification_version = 4
26
26
 
27
- s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.17.1".freeze])
27
+ s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.18.0".freeze])
28
28
  s.add_development_dependency(%q<all_images>.freeze, ["~> 0.4".freeze])
29
29
  s.add_development_dependency(%q<rspec>.freeze, ["~> 3.2".freeze])
30
30
  s.add_development_dependency(%q<webmock>.freeze, [">= 0".freeze])
@@ -45,4 +45,7 @@ Gem::Specification.new do |s|
45
45
  s.add_runtime_dependency(%q<search_ui>.freeze, ["~> 0.0".freeze])
46
46
  s.add_runtime_dependency(%q<amatch>.freeze, ["~> 0.4.1".freeze])
47
47
  s.add_runtime_dependency(%q<pdf-reader>.freeze, ["~> 2.0".freeze])
48
+ s.add_runtime_dependency(%q<logger>.freeze, ["~> 1.0".freeze])
49
+ s.add_runtime_dependency(%q<json>.freeze, ["~> 2.0".freeze])
50
+ s.add_runtime_dependency(%q<xdg>.freeze, ["~> 7.0".freeze])
48
51
  end
@@ -35,6 +35,17 @@ RSpec.describe Ollama::Documents::RedisBackedMemoryCache do
35
35
  expect(cache).to be_a described_class
36
36
  end
37
37
 
38
+ it 'defaults to nil object_class' do
39
+ cache = described_class.new prefix: 'test-', url: 'something'
40
+ expect(cache.object_class).to be_nil
41
+ end
42
+
43
+ it 'can be configured with object_class' do
44
+ object_class = Class.new(JSON::GenericObject)
45
+ cache = described_class.new(prefix: 'test-', url: 'something', object_class:)
46
+ expect(cache.object_class).to eq object_class
47
+ end
48
+
38
49
  it 'has Redis client' do
39
50
  expect(cache.redis).to eq redis
40
51
  end
@@ -6,6 +6,17 @@ RSpec.describe Ollama::Documents::RedisCache do
6
6
  expect(cache).to be_a described_class
7
7
  end
8
8
 
9
+ it 'defaults to nil object_class' do
10
+ cache = described_class.new prefix: 'test-', url: 'something'
11
+ expect(cache.object_class).to be_nil
12
+ end
13
+
14
+ it 'can be configured with object_class' do
15
+ object_class = Class.new(JSON::GenericObject)
16
+ cache = described_class.new(prefix: 'test-', url: 'something', object_class:)
17
+ expect(cache.object_class).to eq object_class
18
+ end
19
+
9
20
  it 'raises ArgumentError if url is missing' do
10
21
  expect {
11
22
  described_class.new prefix: 'test-', url: nil
@@ -37,8 +48,17 @@ RSpec.describe Ollama::Documents::RedisCache do
37
48
 
38
49
  it 'can set a value for a key' do
39
50
  key, value = 'foo', { test: true }
40
- expect(redis).to receive(:set).with('test-' + key, JSON(value))
51
+ expect(redis).to receive(:set).with('test-' + key, JSON(value), ex: nil)
52
+ cache[key] = value
53
+ end
54
+
55
+ it 'can set a value for a key with ttl' do
56
+ cache = described_class.new prefix: 'test-', url: 'something', ex: 3_600
57
+ key, value = 'foo', { test: true }
58
+ expect(redis).to receive(:set).with('test-' + key, JSON(value), ex: 3_600)
41
59
  cache[key] = value
60
+ allow(redis).to receive(:ttl).with('test-' + key).and_return 3_600
61
+ expect(cache.ttl(key)).to eq 3_600
42
62
  end
43
63
 
44
64
  it 'can determine if key exists' do