ollama-ruby 0.3.0 → 0.3.1
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/CHANGES.md +39 -0
- data/README.md +1 -0
- data/Rakefile +2 -2
- data/bin/ollama_chat +52 -31
- data/lib/ollama/utils/width.rb +3 -1
- data/lib/ollama/version.rb +1 -1
- data/ollama-ruby.gemspec +6 -6
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0e3428486bf4d60d1e4a64574a9c04bb41da5a5fe76b5f4bc37c5f089221cf3
|
4
|
+
data.tar.gz: 0a2f6f5269c97b22493400448204116aebef642273c024aee474a38741dfdce5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
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.
|
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
|
-
|
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
|
-
|
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
|
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
|
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
|
-
|
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
|
-
|
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
|
641
|
-
urls
|
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 *
|
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(^/
|
676
|
+
when %r(^/)
|
656
677
|
display_chat_help
|
657
678
|
next
|
658
679
|
when nil, ''
|
data/lib/ollama/utils/width.rb
CHANGED
@@ -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
|
data/lib/ollama/version.rb
CHANGED
data/ollama-ruby.gemspec
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
2
|
-
# stub: ollama-ruby 0.3.
|
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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
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-
|
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.
|
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.
|
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.
|
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.
|
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.
|
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.
|
250
|
+
version: '0.22'
|
251
251
|
- !ruby/object:Gem::Dependency
|
252
252
|
name: search_ui
|
253
253
|
requirement: !ruby/object:Gem::Requirement
|