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 +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
|