ollama-ruby 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 510c31683b2251118a7c3b469620400016b29fd1ea6f17cc86e4f99f62ecea2f
4
- data.tar.gz: a00c4275e42002a01a99f874a855386c83e502551360c1f4146eee0b74f2fd08
3
+ metadata.gz: c0e3428486bf4d60d1e4a64574a9c04bb41da5a5fe76b5f4bc37c5f089221cf3
4
+ data.tar.gz: 0a2f6f5269c97b22493400448204116aebef642273c024aee474a38741dfdce5
5
5
  SHA512:
6
- metadata.gz: 17e50d40e4c24b56b5c2923f0b73f3e4294587b61a302fbaf4cd8f891e879eb435541e1f7e195a4f88352fd99aa80ff44c8577b8c195d7ef31af1c33229018b7
7
- data.tar.gz: a18bcef82e9481b75fee4a4c88598a7a374c48f841e9870b39174c0d1f5f235f1173bdbff939182481d431e4e9c8c85501be4f5ef917ca02865692cfc39fde5a
6
+ metadata.gz: 3fd8db76a1cad30ba41af287e1abb77a102913f09f1648c9fbaf89f5e3bf4f3dace4a39cc6b72da456b633eb42d331b356134aecc196b112c7f94215177b4023
7
+ data.tar.gz: 4541a1e93c2714b786cb21b5e401ffc48a08e05c39bfac860e8cdd275a447bbc7db0b6cf80fee5f459f86734320a90362418a50f4174d53ece4e1a9d2f1dc647
data/CHANGES.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changes
2
2
 
3
+ ## 2024-09-12 v0.3.1
4
+
5
+ * Update dependencies and date in gemspec files:
6
+ - Updated `complex_config` dependency to '~> 0.22'
7
+ * Refactor FollowChat#eval_stats to add bold eval rates
8
+ * Improve formatting in eval_stats using bold and color for better
9
+ readability.
10
+ * Update import_document and add_image methods to handle nil values
11
+ correctly.
12
+ * Update width method in utils/width.rb to use uncolor when checking line
13
+ length.
14
+ * Refactor eval stats output in FollowChat class
15
+ - Add indentation to eval stats output for better readability
16
+ * FollowChat evaluation stats refactored
17
+ - Removed hardcoded eval_stats hash and replaced with method call
18
+ `eval_stats(response)`
19
+ - Added new method `eval_stats(response)` to calculate evaluation statistics
20
+ - Calculates eval duration, prompt eval duration, total duration, and load
21
+ duration
22
+ - Adds eval count, prompt eval count, eval rate, and prompt eval rate
23
+ * Use default to_s tree representation of config.
24
+ * Update complex_config dependency to ~> 0.21, >= 0.21.1 in Rakefile
25
+ * Update complex_config dependency to ~> 0.21, >= 0.21.1 in
26
+ ollama-ruby.gemspec
27
+ * Update dependencies and configuration display
28
+ * Update 'complex_config' dependency to '~> 0.21'
29
+ * Change OllamaChatConfig to display configuration as a tree instead of yaml
30
+ * Improve /web search command
31
+ * Update infobar dependency to ~> 0.8
32
+ * Update /web command to summarize web sources as well as importing them
33
+ directly
34
+ * Add /clobber command to clear conversation messages and collection
35
+ * Refactor Ollama chat configuration and summary generation.
36
+ * Update `OllamaChatConfig` to use `prompts.system` instead of `system`.
37
+ * Introduce `prompts.summarize` config as template for generating abstract
38
+ summaries.
39
+ * Replace hardcoded summary generation with call to `prompts.summarize`.
40
+ * Display /help for all unknown chat commands starting wit `/`
41
+
3
42
  ## 2024-09-05 v0.3.0
4
43
 
5
44
  * **New Features**
data/README.md CHANGED
@@ -156,6 +156,7 @@ The following commands can be given inside the chat, if prefixed by a `/`:
156
156
  /markdown toggle markdown output
157
157
  /list list the messages of the conversation
158
158
  /clear clear the conversation messages
159
+ /clobber clear conversation messages and collection
159
160
  /pop [n] pop the last n exchanges, defaults to 1
160
161
  /model change the model
161
162
  /regenerate the last answer message
data/Rakefile CHANGED
@@ -24,7 +24,7 @@ GemHadar do
24
24
  required_ruby_version '~> 3.1'
25
25
 
26
26
  dependency 'excon', '~> 0.111'
27
- dependency 'infobar', '~> 0.7'
27
+ dependency 'infobar', '~> 0.8'
28
28
  dependency 'term-ansicolor', '~> 1.11'
29
29
  dependency 'kramdown-parser-gfm', '~> 1.1'
30
30
  dependency 'terminal-table', '~> 3.0'
@@ -34,7 +34,7 @@ GemHadar do
34
34
  dependency 'sorted_set', '~> 1.0'
35
35
  dependency 'mime-types', '~> 3.0'
36
36
  dependency 'reverse_markdown', '~> 2.0'
37
- dependency 'complex_config', '~> 0.20'
37
+ dependency 'complex_config', '~> 0.22'
38
38
  dependency 'search_ui', '~> 0.0'
39
39
  dependency 'amatch', '~> 0.4.1'
40
40
  dependency 'pdf-reader', '~> 2.0'
data/bin/ollama_chat CHANGED
@@ -26,7 +26,12 @@ class OllamaChatConfig
26
26
  name: <%= ENV.fetch('OLLAMA_CHAT_MODEL', 'llama3.1') %>
27
27
  options:
28
28
  num_ctx: 8192
29
- system: <%= ENV.fetch('OLLAMA_CHAT_SYSTEM', 'null') %>
29
+ prompts:
30
+ system: <%= ENV.fetch('OLLAMA_CHAT_SYSTEM', 'null') %>
31
+ summarize: |
32
+ Generate an abstract summary of the content in this document:
33
+
34
+ %s
30
35
  voice: Samantha
31
36
  markdown: true
32
37
  embedding:
@@ -50,7 +55,7 @@ class OllamaChatConfig
50
55
 
51
56
  def initialize(filename = nil)
52
57
  @filename = filename || default_path
53
- @config = Provider.config(@filename)
58
+ @config = Provider.config(@filename, '⚙️')
54
59
  retried = false
55
60
  rescue ConfigurationFileMissing
56
61
  if @filename == default_path && !retried
@@ -115,19 +120,28 @@ class FollowChat
115
120
  @say.call(response)
116
121
  end
117
122
  if response.done
118
- @output.puts
119
- eval_stats = {
120
- eval_duration: Tins::Duration.new(response.eval_duration / 1e9),
121
- eval_count: response.eval_count,
122
- prompt_eval_duration: Tins::Duration.new(response.prompt_eval_duration / 1e9),
123
- prompt_eval_count: response.prompt_eval_count,
124
- total_duration: Tins::Duration.new(response.total_duration / 1e9),
125
- load_duration: Tins::Duration.new(response.load_duration / 1e9),
126
- }.map { _1 * '=' } * ' '
127
- @output.puts '📊 ' + color(111) { Utils::Width.wrap(eval_stats, percentage: 90) }
123
+ @output.puts "", eval_stats(response)
128
124
  end
129
125
  self
130
126
  end
127
+
128
+ def eval_stats(response)
129
+ eval_duration = response.eval_duration / 1e9
130
+ prompt_eval_duration = response.prompt_eval_duration / 1e9
131
+ stats_text = {
132
+ eval_duration: Tins::Duration.new(eval_duration),
133
+ eval_count: response.eval_count,
134
+ eval_rate: bold { "%.2f c/s" % (response.eval_count / eval_duration) } + color(111),
135
+ prompt_eval_duration: Tins::Duration.new(prompt_eval_duration),
136
+ prompt_eval_count: response.prompt_eval_count,
137
+ prompt_eval_rate: bold { "%.2f c/s" % (response.prompt_eval_count / prompt_eval_duration) } + color(111),
138
+ total_duration: Tins::Duration.new(response.total_duration / 1e9),
139
+ load_duration: Tins::Duration.new(response.load_duration / 1e9),
140
+ }.map { _1 * '=' } * ' '
141
+ '📊 ' + color(111) {
142
+ Utils::Width.wrap(stats_text, percentage: 90).gsub(/(?<!\A)^/, ' ')
143
+ }
144
+ end
131
145
  end
132
146
 
133
147
  def search_web(query, n = 5)
@@ -312,7 +326,7 @@ def import_document(source_io, source)
312
326
  STDOUT.puts "Embedding disabled, I won't import any documents, try: /summarize"
313
327
  return
314
328
  end
315
- infobar.puts "Importing #{italic { source_io.content_type }} document #{source.to_s.inspect}."
329
+ puts "Importing #{italic { source_io&.content_type }} document #{source.to_s.inspect}."
316
330
  text = parse_source(source_io) or return
317
331
  text.downcase!
318
332
  splitter_config = $config.embedding.splitter
@@ -340,7 +354,7 @@ def import_document(source_io, source)
340
354
  end
341
355
 
342
356
  def add_image(images, source_io, source)
343
- STDERR.puts "Adding #{source_io.content_type} image #{source.to_s.inspect}."
357
+ STDERR.puts "Adding #{source_io&.content_type} image #{source.to_s.inspect}."
344
358
  image = Image.for_io(source_io, path: source.to_s)
345
359
  (images << image).uniq!
346
360
  end
@@ -365,16 +379,12 @@ rescue => e
365
379
  end
366
380
 
367
381
  def summarize(source)
368
- puts "Now summarizing #{source.inspect}."
382
+ puts "Now summarizing #{source.to_s.inspect}."
369
383
  source_content =
370
384
  fetch_source(source) do |source_io|
371
385
  parse_source(source_io) or return
372
386
  end
373
- <<~end
374
- # Generate an abstract summary of the content in this document:
375
-
376
- #{source_content}
377
- end
387
+ $config.prompts.summarize % source_content
378
388
  end
379
389
 
380
390
  def parse_content(content, images)
@@ -459,6 +469,7 @@ def display_chat_help
459
469
  /markdown toggle markdown output
460
470
  /list list the messages of the conversation
461
471
  /clear clear the conversation messages
472
+ /clobber clear conversation messages and collection
462
473
  /pop [n] pop the last n exchanges, defaults to 1
463
474
  /model change the model
464
475
  /regenerate the last answer message
@@ -501,8 +512,7 @@ $config = config.config
501
512
 
502
513
  opts[?h] and usage
503
514
 
504
- puts "Configuration read from #{config.filename.inspect} is:"
505
- y $config.to_h
515
+ puts "Configuration read from #{config.filename.inspect} is:", $config
506
516
 
507
517
  base_url = opts[?u] || $config.url
508
518
  $ollama = Client.new(base_url:, debug: $config.debug)
@@ -540,7 +550,7 @@ if $config.embedding.enabled
540
550
  File.expand_path(doc)
541
551
  end
542
552
  end
543
- infobar.puts "Collection #{bold{collection}}: Adding #{document_list.size} documents…"
553
+ puts "Collection #{bold{collection}}: Adding #{document_list.size} documents…"
544
554
  document_list.each_slice(25) do |docs|
545
555
  docs.each do |doc|
546
556
  fetch_source(doc) do |doc_io|
@@ -563,7 +573,7 @@ if opts[?c]
563
573
  messages.concat load_conversation(opts[?c])
564
574
  else
565
575
  if system = Ollama::Utils::FileArgument.
566
- get_file_argument(opts[?s], default: $config.system? || model_system)
576
+ get_file_argument(opts[?s], default: $config.prompts.system? || model_system)
567
577
  messages << Message.new(role: 'system', content: system)
568
578
  puts "Configured system prompt is:\n#{italic { system }}"
569
579
  end
@@ -584,7 +594,7 @@ loop do
584
594
  when %r(^/quit$)
585
595
  puts "Goodbye."
586
596
  exit 0
587
- when %r(^/markdown)
597
+ when %r(^/markdown$)
588
598
  markdown = set_markdown(!markdown)
589
599
  next
590
600
  when %r(^/list$)
@@ -594,6 +604,11 @@ loop do
594
604
  messages.clear
595
605
  puts "Cleared messages."
596
606
  next
607
+ when %r(^/clobber$)
608
+ messages.clear
609
+ $documents.clear
610
+ puts "Cleared messages and collection."
611
+ next
597
612
  when %r(^/collection\s+(clear|stats|change|new)(?:\s+(.+))?$)
598
613
  command, arg = $1, $2
599
614
  case command
@@ -636,13 +651,19 @@ loop do
636
651
  when %r(^/summarize\s+(.+))
637
652
  parse_content = false
638
653
  content = summarize($1) or next
639
- when %r(^/web\s+(?:(\d+)\s+)?(.+)$)
640
- parse_content = true
641
- urls = search_web($2, $1.to_i)
654
+ when %r(^/web\s+(?:(\d+)\s+)?(.+))
655
+ parse_content = false
656
+ urls = search_web($2, $1.to_i)
657
+ urls.each do |url|
658
+ fetch_source(url) do |url_io|
659
+ import_document(url_io, url)
660
+ end
661
+ end
662
+ urls_summarized = urls.map { summarize(_1) }
642
663
  content = <<~end
643
- Answer the the query #{$2.inspect} using these sources:
664
+ Answer the the query #{$2.inspect} using these sources and summaries:
644
665
 
645
- #{urls * ?\n}
666
+ #{urls.zip(urls_summarized).map { |u, s| "%s as \n:%s" % [ u, s ] } * "\n\n"}
646
667
  end
647
668
  when %r(^/save\s+(.+)$)
648
669
  save_conversation($1, messages)
@@ -652,7 +673,7 @@ loop do
652
673
  messages = load_conversation($1)
653
674
  puts "Loaded conversation from #$1."
654
675
  next
655
- when %r(^/help$)
676
+ when %r(^/)
656
677
  display_chat_help
657
678
  next
658
679
  when nil, ''
@@ -1,6 +1,8 @@
1
1
  require 'tins/terminal'
2
2
 
3
3
  module Ollama::Utils::Width
4
+ include Term::ANSIColor
5
+
4
6
  module_function
5
7
 
6
8
  def width(percentage: 100.0)
@@ -12,7 +14,7 @@ module Ollama::Utils::Width
12
14
  raise ArgumentError, "either pass percentage or length argument"
13
15
  percentage and length ||= width(percentage:)
14
16
  text.gsub(/(?<!\n)\n(?!\n)/, ' ').lines.map do |line|
15
- if length >= 1 && line.length > length
17
+ if length >= 1 && uncolor { line }.length > length
16
18
  line.gsub(/(.{1,#{length}})(\s+|$)/, "\\1\n").strip
17
19
  else
18
20
  line.strip
@@ -1,6 +1,6 @@
1
1
  module Ollama
2
2
  # Ollama version
3
- VERSION = '0.3.0'
3
+ VERSION = '0.3.1'
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/ollama-ruby.gemspec CHANGED
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: ollama-ruby 0.3.0 ruby lib
2
+ # stub: ollama-ruby 0.3.1 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ollama-ruby".freeze
6
- s.version = "0.3.0".freeze
6
+ s.version = "0.3.1".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-06"
11
+ s.date = "2024-09-12"
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]
@@ -24,13 +24,13 @@ Gem::Specification.new do |s|
24
24
 
25
25
  s.specification_version = 4
26
26
 
27
- s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.17.0".freeze])
27
+ s.add_development_dependency(%q<gem_hadar>.freeze, ["~> 1.17.1".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<utils>.freeze, [">= 0".freeze])
31
31
  s.add_development_dependency(%q<webmock>.freeze, [">= 0".freeze])
32
32
  s.add_runtime_dependency(%q<excon>.freeze, ["~> 0.111".freeze])
33
- s.add_runtime_dependency(%q<infobar>.freeze, ["~> 0.7".freeze])
33
+ s.add_runtime_dependency(%q<infobar>.freeze, ["~> 0.8".freeze])
34
34
  s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.11".freeze])
35
35
  s.add_runtime_dependency(%q<kramdown-parser-gfm>.freeze, ["~> 1.1".freeze])
36
36
  s.add_runtime_dependency(%q<terminal-table>.freeze, ["~> 3.0".freeze])
@@ -40,7 +40,7 @@ Gem::Specification.new do |s|
40
40
  s.add_runtime_dependency(%q<sorted_set>.freeze, ["~> 1.0".freeze])
41
41
  s.add_runtime_dependency(%q<mime-types>.freeze, ["~> 3.0".freeze])
42
42
  s.add_runtime_dependency(%q<reverse_markdown>.freeze, ["~> 2.0".freeze])
43
- s.add_runtime_dependency(%q<complex_config>.freeze, ["~> 0.20".freeze])
43
+ s.add_runtime_dependency(%q<complex_config>.freeze, ["~> 0.22".freeze])
44
44
  s.add_runtime_dependency(%q<search_ui>.freeze, ["~> 0.0".freeze])
45
45
  s.add_runtime_dependency(%q<amatch>.freeze, ["~> 0.4.1".freeze])
46
46
  s.add_runtime_dependency(%q<pdf-reader>.freeze, ["~> 2.0".freeze])
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ollama-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-09-06 00:00:00.000000000 Z
11
+ date: 2024-09-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gem_hadar
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 1.17.0
19
+ version: 1.17.1
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 1.17.0
26
+ version: 1.17.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: all_images
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - "~>"
102
102
  - !ruby/object:Gem::Version
103
- version: '0.7'
103
+ version: '0.8'
104
104
  type: :runtime
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
- version: '0.7'
110
+ version: '0.8'
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: term-ansicolor
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -240,14 +240,14 @@ dependencies:
240
240
  requirements:
241
241
  - - "~>"
242
242
  - !ruby/object:Gem::Version
243
- version: '0.20'
243
+ version: '0.22'
244
244
  type: :runtime
245
245
  prerelease: false
246
246
  version_requirements: !ruby/object:Gem::Requirement
247
247
  requirements:
248
248
  - - "~>"
249
249
  - !ruby/object:Gem::Version
250
- version: '0.20'
250
+ version: '0.22'
251
251
  - !ruby/object:Gem::Dependency
252
252
  name: search_ui
253
253
  requirement: !ruby/object:Gem::Requirement