ollama_chat 0.0.2 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
data/docker-compose.yml CHANGED
@@ -1,10 +1,31 @@
1
1
  services:
2
2
  redis:
3
+ container_name: redis
3
4
  image: valkey/valkey:7.2.8-alpine
4
5
  restart: unless-stopped
5
6
  ports: [ "127.0.0.1:9736:6379" ]
6
7
  volumes:
7
8
  - "redis-data:/data:delegated"
8
9
  - "./redis/redis.conf:/etc/redis.conf"
10
+ searxng:
11
+ container_name: searxng
12
+ image: searxng/searxng:latest
13
+ ports:
14
+ - "127.0.0.1:8088:8080"
15
+ restart: unless-stopped
16
+ cap_drop:
17
+ - ALL
18
+ cap_add:
19
+ - CHOWN
20
+ - SETGID
21
+ - SETUID
22
+ - DAC_OVERRIDE
23
+ logging:
24
+ driver: "json-file"
25
+ options:
26
+ max-size: "1m"
27
+ max-file: "1"
28
+ volumes:
29
+ - "./config/searxng:/etc/searxng"
9
30
  volumes:
10
31
  redis-data:
@@ -19,6 +19,7 @@ class OllamaChat::Chat
19
19
  include OllamaChat::ModelHandling
20
20
  include OllamaChat::Parsing
21
21
  include OllamaChat::SourceFetching
22
+ include OllamaChat::WebSearching
22
23
  include OllamaChat::Dialog
23
24
  include OllamaChat::Information
24
25
  include OllamaChat::Clipboard
@@ -37,6 +38,7 @@ class OllamaChat::Chat
37
38
  debug: config.debug,
38
39
  user_agent:
39
40
  )
41
+ server_version
40
42
  @document_policy = config.document_policy
41
43
  @model = choose_model(@opts[?m], config.model.name)
42
44
  @model_options = Ollama::Options[config.model.options]
@@ -200,7 +202,7 @@ class OllamaChat::Chat
200
202
  content = embed($1) or next
201
203
  when %r(^/web\s+(?:(\d+)\s+)?(.+))
202
204
  parse_content = false
203
- urls = search_web($2, $1.to_i)
205
+ urls = search_web($2, $1.to_i) or next
204
206
  urls.each do |url|
205
207
  fetch_source(url) { |url_io| embed_source(url_io, url) }
206
208
  end
@@ -391,7 +393,7 @@ class OllamaChat::Chat
391
393
  Documentrix::Documents::RedisCache.new(
392
394
  prefix: 'Expiring-',
393
395
  url:,
394
- ex: config.redis.expiring.ex,
396
+ ex: config.redis.expiring.ex?.to_i,
395
397
  )
396
398
  end
397
399
  end
@@ -28,6 +28,8 @@ module OllamaChat::Information
28
28
  end
29
29
 
30
30
  def info
31
+ STDOUT.puts "Running ollama_chat version: #{bold(OllamaChat::VERSION)}"
32
+ STDOUT.puts "Connected to ollama server version: #{bold(server_version)}"
31
33
  STDOUT.puts "Current model is #{bold{@model}}."
32
34
  if @model_options.present?
33
35
  STDOUT.puts " Options: #{JSON.pretty_generate(@model_options).gsub(/(?<!\A)^/, ' ')}"
@@ -46,6 +48,7 @@ module OllamaChat::Information
46
48
  stream.show
47
49
  location.show
48
50
  STDOUT.puts "Document policy for references in user text: #{bold{@document_policy}}"
51
+ STDOUT.puts "Currently selected search engine is #{bold(search_engine)}."
49
52
  if @voice.on?
50
53
  STDOUT.puts "Using voice #{bold{@current_voice}} to speak."
51
54
  end
@@ -110,4 +113,8 @@ module OllamaChat::Information
110
113
  STDOUT.puts "%s %s" % [ progname, OllamaChat::VERSION ]
111
114
  0
112
115
  end
116
+
117
+ def server_version
118
+ @server_version ||= ollama.version.version
119
+ end
113
120
  end
@@ -56,5 +56,14 @@ redis:
56
56
  url: <%= ENV.fetch('REDIS_EXPIRING_URL', 'null') %>
57
57
  ex: 86400
58
58
  debug: <%= ENV['OLLAMA_CHAT_DEBUG'].to_i == 1 ? true : false %>
59
+ request_headers:
60
+ Accept: 'text/*,application/*,image/*'
59
61
  ssl_no_verify: []
60
62
  copy: pbcopy
63
+ web_search:
64
+ use: duckduckgo
65
+ engines:
66
+ duckduckgo:
67
+ url: 'https://www.duckduckgo.com/html/?q=%{query}'
68
+ searxng:
69
+ url: 'http://localhost:8088/search?q=%{query}&format=json'
@@ -22,6 +22,7 @@ module OllamaChat::SourceFetching
22
22
  links.add(source.to_s)
23
23
  OllamaChat::Utils::Fetcher.get(
24
24
  source,
25
+ headers: config.request_headers?.to_h,
25
26
  cache: @cache,
26
27
  debug: config.debug,
27
28
  http_options: http_options(OllamaChat::Utils::Fetcher.normalize_url(source))
@@ -140,33 +141,4 @@ module OllamaChat::SourceFetching
140
141
  summarize(source)
141
142
  end
142
143
  end
143
-
144
- def search_web(query, n = nil)
145
- if l = @messages.at_location.full?
146
- query += " #{l}"
147
- end
148
- n = n.to_i.clamp(1..)
149
- query = URI.encode_uri_component(query)
150
- url = "https://www.duckduckgo.com/html/?q=#{query}"
151
- OllamaChat::Utils::Fetcher.get(url, debug: config.debug) do |tmp|
152
- result = []
153
- doc = Nokogiri::HTML(tmp)
154
- doc.css('.results_links').each do |link|
155
- if n > 0
156
- url = link.css('.result__a').first&.[]('href')
157
- url.sub!(%r(\A(//duckduckgo\.com)?/l/\?uddg=), '')
158
- url.sub!(%r(&rut=.*), '')
159
- url = URI.decode_uri_component(url)
160
- url = URI.parse(url)
161
- url.host =~ /duckduckgo\.com/ and next
162
- links.add(url.to_s)
163
- result << url
164
- n -= 1
165
- else
166
- break
167
- end
168
- end
169
- result
170
- end
171
- end
172
144
  end
@@ -20,14 +20,14 @@ class OllamaChat::Utils::Fetcher
20
20
 
21
21
  class RetryWithoutStreaming < StandardError; end
22
22
 
23
- def self.get(url, **options, &block)
23
+ def self.get(url, headers: {}, **options, &block)
24
24
  cache = options.delete(:cache) and
25
25
  cache = OllamaChat::Utils::CacheFetcher.new(cache)
26
26
  if result = cache&.get(url, &block)
27
27
  infobar.puts "Getting #{url.to_s.inspect} from cache."
28
28
  return result
29
29
  else
30
- new(**options).send(:get, url) do |tmp|
30
+ new(**options).send(:get, url, headers:) do |tmp|
31
31
  result = block.(tmp)
32
32
  if cache && !tmp.is_a?(StringIO)
33
33
  tmp.rewind
@@ -91,7 +91,9 @@ class OllamaChat::Utils::Fetcher
91
91
  Excon.new(url, options.merge(@http_options))
92
92
  end
93
93
 
94
- def get(url, &block)
94
+ def get(url, headers: {}, &block)
95
+ headers |= self.headers
96
+ headers = headers.transform_keys(&:to_s)
95
97
  response = nil
96
98
  Tempfile.open do |tmp|
97
99
  infobar.label = 'Getting'
@@ -1,6 +1,6 @@
1
1
  module OllamaChat
2
2
  # OllamaChat version
3
- VERSION = '0.0.2'
3
+ VERSION = '0.0.4'
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:
@@ -0,0 +1,60 @@
1
+ module OllamaChat::WebSearching
2
+ def search_web(query, n = nil)
3
+ l = @messages.at_location.full? and query += " #{l}"
4
+ n = n.to_i.clamp(1..)
5
+ query = URI.encode_uri_component(query)
6
+ search_command = :"search_web_with_#{search_engine}"
7
+ if respond_to?(search_command, true)
8
+ send(search_command, query, n)
9
+ else
10
+ STDOUT.puts "Search engine #{bold{search_engine}} not implemented!"
11
+ nil
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def search_engine
18
+ config.web_search.use
19
+ end
20
+
21
+ def search_web_with_searxng(query, n)
22
+ url = config.web_search.engines.searxng.url % { query: }
23
+ OllamaChat::Utils::Fetcher.get(
24
+ url,
25
+ headers: config.request_headers?.to_h,
26
+ debug: config.debug
27
+ ) do |tmp|
28
+ data = JSON.parse(tmp.read, object_class: JSON::GenericObject)
29
+ data.results.first(n).map(&:url)
30
+ end
31
+ end
32
+
33
+ def search_web_with_duckduckgo(query, n)
34
+ url = config.web_search.engines.duckduckgo.url % { query: }
35
+ OllamaChat::Utils::Fetcher.get(
36
+ url,
37
+ headers: config.request_headers?.to_h,
38
+ debug: config.debug
39
+ ) do |tmp|
40
+ result = []
41
+ doc = Nokogiri::HTML(tmp)
42
+ doc.css('.results_links').each do |link|
43
+ if n > 0
44
+ url = link.css('.result__a').first&.[]('href')
45
+ url.sub!(%r(\A(//duckduckgo\.com)?/l/\?uddg=), '')
46
+ url.sub!(%r(&rut=.*), '')
47
+ url = URI.decode_uri_component(url)
48
+ url = URI.parse(url)
49
+ url.host =~ /duckduckgo\.com/ and next
50
+ links.add(url.to_s)
51
+ result << url
52
+ n -= 1
53
+ else
54
+ break
55
+ end
56
+ end
57
+ result
58
+ end
59
+ end
60
+ end
data/lib/ollama_chat.rb CHANGED
@@ -13,6 +13,7 @@ require 'ollama_chat/message_list'
13
13
  require 'ollama_chat/model_handling'
14
14
  require 'ollama_chat/parsing'
15
15
  require 'ollama_chat/source_fetching'
16
+ require 'ollama_chat/web_searching'
16
17
  require 'ollama_chat/dialog'
17
18
  require 'ollama_chat/information'
18
19
  require 'ollama_chat/clipboard'
data/ollama_chat.gemspec CHANGED
@@ -1,26 +1,26 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: ollama_chat 0.0.2 ruby lib
2
+ # stub: ollama_chat 0.0.4 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ollama_chat".freeze
6
- s.version = "0.0.2".freeze
6
+ s.version = "0.0.4".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 = "2025-02-12"
11
+ s.date = "2025-02-21"
12
12
  s.description = "The app provides a command-line interface (CLI) to an Ollama AI model,\nallowing users to engage in text-based conversations and generate\nhuman-like responses. Users can import data from local files or web pages,\nwhich are then processed through three different modes: fully importing the\ncontent into the conversation context, summarizing the information for\nconcise reference, or storing it in an embedding vector database for later\nretrieval based on the conversation.\n".freeze
13
13
  s.email = "flori@ping.de".freeze
14
14
  s.executables = ["ollama_chat".freeze]
15
- s.extra_rdoc_files = ["README.md".freeze, "lib/ollama_chat.rb".freeze, "lib/ollama_chat/chat.rb".freeze, "lib/ollama_chat/clipboard.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/message_list.rb".freeze, "lib/ollama_chat/message_type.rb".freeze, "lib/ollama_chat/model_handling.rb".freeze, "lib/ollama_chat/ollama_chat_config.rb".freeze, "lib/ollama_chat/parsing.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/utils.rb".freeze, "lib/ollama_chat/utils/cache_fetcher.rb".freeze, "lib/ollama_chat/utils/chooser.rb".freeze, "lib/ollama_chat/utils/fetcher.rb".freeze, "lib/ollama_chat/utils/file_argument.rb".freeze, "lib/ollama_chat/version.rb".freeze]
16
- s.files = [".all_images.yml".freeze, ".envrc".freeze, ".gitignore".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/ollama_chat".freeze, "docker-compose.yml".freeze, "lib/ollama_chat.rb".freeze, "lib/ollama_chat/chat.rb".freeze, "lib/ollama_chat/clipboard.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/message_list.rb".freeze, "lib/ollama_chat/message_type.rb".freeze, "lib/ollama_chat/model_handling.rb".freeze, "lib/ollama_chat/ollama_chat_config.rb".freeze, "lib/ollama_chat/ollama_chat_config/default_config.yml".freeze, "lib/ollama_chat/parsing.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/utils.rb".freeze, "lib/ollama_chat/utils/cache_fetcher.rb".freeze, "lib/ollama_chat/utils/chooser.rb".freeze, "lib/ollama_chat/utils/fetcher.rb".freeze, "lib/ollama_chat/utils/file_argument.rb".freeze, "lib/ollama_chat/version.rb".freeze, "ollama_chat.gemspec".freeze, "redis/redis.conf".freeze, "spec/assets/api_show.json".freeze, "spec/assets/api_tags.json".freeze, "spec/assets/conversation.json".freeze, "spec/assets/duckduckgo.html".freeze, "spec/assets/example.atom".freeze, "spec/assets/example.csv".freeze, "spec/assets/example.html".freeze, "spec/assets/example.pdf".freeze, "spec/assets/example.ps".freeze, "spec/assets/example.rb".freeze, "spec/assets/example.rss".freeze, "spec/assets/example.xml".freeze, "spec/assets/kitten.jpg".freeze, "spec/assets/prompt.txt".freeze, "spec/ollama_chat/chat_spec.rb".freeze, "spec/ollama_chat/clipboard_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/file_argument_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tmp/.keep".freeze]
15
+ s.extra_rdoc_files = ["README.md".freeze, "lib/ollama_chat.rb".freeze, "lib/ollama_chat/chat.rb".freeze, "lib/ollama_chat/clipboard.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/message_list.rb".freeze, "lib/ollama_chat/message_type.rb".freeze, "lib/ollama_chat/model_handling.rb".freeze, "lib/ollama_chat/ollama_chat_config.rb".freeze, "lib/ollama_chat/parsing.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/utils.rb".freeze, "lib/ollama_chat/utils/cache_fetcher.rb".freeze, "lib/ollama_chat/utils/chooser.rb".freeze, "lib/ollama_chat/utils/fetcher.rb".freeze, "lib/ollama_chat/utils/file_argument.rb".freeze, "lib/ollama_chat/version.rb".freeze, "lib/ollama_chat/web_searching.rb".freeze]
16
+ s.files = [".all_images.yml".freeze, ".envrc".freeze, ".gitignore".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "VERSION".freeze, "bin/ollama_chat".freeze, "config/searxng/settings.yml".freeze, "docker-compose.yml".freeze, "lib/ollama_chat.rb".freeze, "lib/ollama_chat/chat.rb".freeze, "lib/ollama_chat/clipboard.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/message_list.rb".freeze, "lib/ollama_chat/message_type.rb".freeze, "lib/ollama_chat/model_handling.rb".freeze, "lib/ollama_chat/ollama_chat_config.rb".freeze, "lib/ollama_chat/ollama_chat_config/default_config.yml".freeze, "lib/ollama_chat/parsing.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/utils.rb".freeze, "lib/ollama_chat/utils/cache_fetcher.rb".freeze, "lib/ollama_chat/utils/chooser.rb".freeze, "lib/ollama_chat/utils/fetcher.rb".freeze, "lib/ollama_chat/utils/file_argument.rb".freeze, "lib/ollama_chat/version.rb".freeze, "lib/ollama_chat/web_searching.rb".freeze, "ollama_chat.gemspec".freeze, "redis/redis.conf".freeze, "spec/assets/api_show.json".freeze, "spec/assets/api_tags.json".freeze, "spec/assets/api_version.json".freeze, "spec/assets/conversation.json".freeze, "spec/assets/duckduckgo.html".freeze, "spec/assets/example.atom".freeze, "spec/assets/example.csv".freeze, "spec/assets/example.html".freeze, "spec/assets/example.pdf".freeze, "spec/assets/example.ps".freeze, "spec/assets/example.rb".freeze, "spec/assets/example.rss".freeze, "spec/assets/example.xml".freeze, "spec/assets/kitten.jpg".freeze, "spec/assets/prompt.txt".freeze, "spec/assets/searxng.json".freeze, "spec/ollama_chat/chat_spec.rb".freeze, "spec/ollama_chat/clipboard_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/file_argument_spec.rb".freeze, "spec/ollama_chat/web_searching_spec.rb".freeze, "spec/spec_helper.rb".freeze, "tmp/.keep".freeze]
17
17
  s.homepage = "https://github.com/flori/ollama_chat".freeze
18
18
  s.licenses = ["MIT".freeze]
19
19
  s.rdoc_options = ["--title".freeze, "OllamaChat - A command-line interface (CLI) for interacting with an Ollama AI model.".freeze, "--main".freeze, "README.md".freeze]
20
20
  s.required_ruby_version = Gem::Requirement.new("~> 3.1".freeze)
21
21
  s.rubygems_version = "3.6.2".freeze
22
22
  s.summary = "A command-line interface (CLI) for interacting with an Ollama AI model.".freeze
23
- s.test_files = ["spec/assets/example.rb".freeze, "spec/ollama_chat/chat_spec.rb".freeze, "spec/ollama_chat/clipboard_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/file_argument_spec.rb".freeze, "spec/spec_helper.rb".freeze]
23
+ s.test_files = ["spec/assets/example.rb".freeze, "spec/ollama_chat/chat_spec.rb".freeze, "spec/ollama_chat/clipboard_spec.rb".freeze, "spec/ollama_chat/follow_chat_spec.rb".freeze, "spec/ollama_chat/information_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/utils/cache_fetcher_spec.rb".freeze, "spec/ollama_chat/utils/fetcher_spec.rb".freeze, "spec/ollama_chat/utils/file_argument_spec.rb".freeze, "spec/ollama_chat/web_searching_spec.rb".freeze, "spec/spec_helper.rb".freeze]
24
24
 
25
25
  s.specification_version = 4
26
26
 
@@ -32,7 +32,7 @@ Gem::Specification.new do |s|
32
32
  s.add_development_dependency(%q<debug>.freeze, [">= 0".freeze])
33
33
  s.add_development_dependency(%q<simplecov>.freeze, [">= 0".freeze])
34
34
  s.add_runtime_dependency(%q<excon>.freeze, ["~> 1.0".freeze])
35
- s.add_runtime_dependency(%q<ollama-ruby>.freeze, ["~> 0.14".freeze])
35
+ s.add_runtime_dependency(%q<ollama-ruby>.freeze, ["~> 0.15".freeze])
36
36
  s.add_runtime_dependency(%q<documentrix>.freeze, ["~> 0.0".freeze])
37
37
  s.add_runtime_dependency(%q<rss>.freeze, ["~> 0.3".freeze])
38
38
  s.add_runtime_dependency(%q<term-ansicolor>.freeze, ["~> 1.11".freeze])
@@ -0,0 +1,3 @@
1
+ {
2
+ "version": "6.6.6"
3
+ }
@@ -0,0 +1,111 @@
1
+ {
2
+ "query": "foo",
3
+ "number_of_results": 0,
4
+ "results": [
5
+ {
6
+ "url": "https://en.wikipedia.org/wiki/Foo_Fighters",
7
+ "title": "Foo Fighters - Wikipedia",
8
+ "content": "The Foo Fighters are an American rock band formed in Seattle in 1994. Initially founded as a one-man project by former Nirvana drummer Dave Grohl, the band comprises vocalist/guitarist Grohl, bassist Nate Mendel, guitarist Pat Smear, guitarist Chris Shiflett, keyboardist Rami Jaffee and drummer Josh Freese.Guitarist Franz Stahl and drummers William Goldsmith and Taylor Hawkins are former ...",
9
+ "publishedDate": null,
10
+ "thumbnail": null,
11
+ "engine": "brave",
12
+ "template": "default.html",
13
+ "parsed_url": [
14
+ "https",
15
+ "en.wikipedia.org",
16
+ "/wiki/Foo_Fighters",
17
+ "",
18
+ "",
19
+ ""
20
+ ],
21
+ "engines": [
22
+ "startpage",
23
+ "brave",
24
+ "google",
25
+ "duckduckgo"
26
+ ],
27
+ "positions": [
28
+ 2,
29
+ 1,
30
+ 2,
31
+ 1
32
+ ],
33
+ "score": 12.0,
34
+ "category": "general"
35
+ },
36
+ {
37
+ "url": "https://www.foofighters.com",
38
+ "title": "Home - Foo Fighters",
39
+ "content": "Official website of Foo Fighters",
40
+ "publishedDate": "2023-04-19T00:00:00",
41
+ "thumbnail": null,
42
+ "engine": "brave",
43
+ "template": "default.html",
44
+ "parsed_url": [
45
+ "https",
46
+ "www.foofighters.com",
47
+ "",
48
+ "",
49
+ "",
50
+ ""
51
+ ],
52
+ "engines": [
53
+ "startpage",
54
+ "brave",
55
+ "google",
56
+ "duckduckgo"
57
+ ],
58
+ "positions": [
59
+ 1,
60
+ 2,
61
+ 7,
62
+ 2
63
+ ],
64
+ "score": 8.571428571428571,
65
+ "category": "general"
66
+ },
67
+ {
68
+ "url": "https://www.dictionary.com/e/tech-science/foo/",
69
+ "title": "foo | Meaning & Origin | Dictionary.com",
70
+ "content": "\"Foo was here\" was a popular piece of graffiti drawn by Australian soldiers in WWII, and possibly even WWI, that depicts a little man poking his head and large nose over the wall à la Kilroy. While the origins of this foo are unclear, it appears to be unrelated to Holman's foo.",
71
+ "publishedDate": "2022-07-04T00:00:00",
72
+ "thumbnail": "",
73
+ "engine": "brave",
74
+ "template": "default.html",
75
+ "parsed_url": [
76
+ "https",
77
+ "www.dictionary.com",
78
+ "/e/tech-science/foo/",
79
+ "",
80
+ "",
81
+ ""
82
+ ],
83
+ "engines": [
84
+ "brave",
85
+ "duckduckgo"
86
+ ],
87
+ "positions": [
88
+ 13,
89
+ 1
90
+ ],
91
+ "score": 2.1538461538461537,
92
+ "category": "general"
93
+ }
94
+ ],
95
+ "suggestions": [
96
+ "foo fighters - everlong",
97
+ "Foo meaning",
98
+ "Foo Fighters WW2",
99
+ "Foo Fighters - Learn to Fly",
100
+ "foo fighters - the colour and the shape",
101
+ "Foo Fighters tour 2024",
102
+ "Foo programming",
103
+ "Foo word"
104
+ ],
105
+ "unresponsive_engines": [
106
+ [
107
+ "qwant",
108
+ "Suspended: CAPTCHA"
109
+ ]
110
+ ]
111
+ }
@@ -2,19 +2,14 @@ require 'spec_helper'
2
2
 
3
3
  RSpec.describe OllamaChat::Chat do
4
4
  let :argv do
5
- []
5
+ %w[ -C test ]
6
6
  end
7
7
 
8
8
  let :chat do
9
9
  OllamaChat::Chat.new argv: argv
10
10
  end
11
11
 
12
- before do
13
- stub_request(:get, %r(/api/tags\z)).
14
- to_return(status: 200, body: asset_json('api_tags.json'))
15
- stub_request(:post, %r(/api/show\z)).
16
- to_return(status: 200, body: asset_json('api_show.json'))
17
- end
12
+ connect_to_ollama_server(instantiate: false)
18
13
 
19
14
  it 'can be instantiated' do
20
15
  expect(chat).to be_a described_class
@@ -43,7 +38,7 @@ RSpec.describe OllamaChat::Chat do
43
38
  describe Documentrix::Documents do
44
39
  context 'with documents' do
45
40
  let :argv do
46
- %w[ -D ] << asset('example.html')
41
+ %w[ -C test -D ] << asset('example.html')
47
42
  end
48
43
 
49
44
  it 'Adds documents passed to app via -D option' do
@@ -66,7 +61,7 @@ RSpec.describe OllamaChat::Chat do
66
61
  it 'can display collection_stats' do
67
62
  chat
68
63
  expect(STDOUT).to receive(:puts).with(
69
- "Current Collection\n Name: \e[1mdefault\e[0m\n #Embeddings: 0\n #Tags: 0\n Tags: \n"
64
+ "Current Collection\n Name: \e[1mtest\e[0m\n #Embeddings: 0\n #Tags: 0\n Tags: \n"
70
65
  )
71
66
  expect(chat.collection_stats).to be_nil
72
67
  end
@@ -76,6 +71,8 @@ RSpec.describe OllamaChat::Chat do
76
71
  expect(STDOUT).to receive(:puts).
77
72
  with(
78
73
  /
74
+ Running\ ollama_chat\ version|
75
+ Connected\ to\ ollama\ server|
79
76
  Current\ model|
80
77
  Options|
81
78
  Embedding|
@@ -84,7 +81,8 @@ RSpec.describe OllamaChat::Chat do
84
81
  output\ content|
85
82
  Streaming|
86
83
  Location|
87
- Document\ policy
84
+ Document\ policy|
85
+ Currently\ selected\ search\ engine
88
86
  /x
89
87
  ).at_least(1)
90
88
  expect(chat.info).to be_nil
@@ -5,13 +5,7 @@ RSpec.describe OllamaChat::Clipboard do
5
5
  OllamaChat::Chat.new
6
6
  end
7
7
 
8
- before do
9
- stub_request(:get, %r(/api/tags\z)).
10
- to_return(status: 200, body: asset_json('api_tags.json'))
11
- stub_request(:post, %r(/api/show\z)).
12
- to_return(status: 200, body: asset_json('api_show.json'))
13
- chat
14
- end
8
+ connect_to_ollama_server
15
9
 
16
10
  it 'can copy to clipboard' do
17
11
  expect(STDERR).to receive(:puts).with(/No response available to copy to the system clipboard/)
@@ -5,13 +5,7 @@ RSpec.describe OllamaChat::Information do
5
5
  OllamaChat::Chat.new
6
6
  end
7
7
 
8
- before do
9
- stub_request(:get, %r(/api/tags\z)).
10
- to_return(status: 200, body: asset_json('api_tags.json'))
11
- stub_request(:post, %r(/api/show\z)).
12
- to_return(status: 200, body: asset_json('api_show.json'))
13
- chat
14
- end
8
+ connect_to_ollama_server
15
9
 
16
10
  describe ::OllamaChat::Information::UserAgent do
17
11
  it 'has progname' do
@@ -29,6 +23,7 @@ RSpec.describe OllamaChat::Information do
29
23
  end
30
24
 
31
25
  it 'can show info' do
26
+ expect(STDOUT).to receive(:puts).with(/Connected to ollama server version/)
32
27
  expect(STDOUT).to receive(:puts).with(/Current model is/)
33
28
  expect(STDOUT).to receive(:puts).at_least(1)
34
29
  expect(chat.info).to be_nil
@@ -5,13 +5,7 @@ RSpec.describe OllamaChat::ModelHandling do
5
5
  OllamaChat::Chat.new
6
6
  end
7
7
 
8
- before do
9
- stub_request(:get, %r(/api/tags\z)).
10
- to_return(status: 200, body: asset_json('api_tags.json'))
11
- stub_request(:post, %r(/api/show\z)).
12
- to_return(status: 200, body: asset_json('api_show.json'))
13
- chat
14
- end
8
+ connect_to_ollama_server
15
9
 
16
10
  it 'can check if model_present?' do
17
11
  expect(chat.ollama).to receive(:show).and_raise Ollama::Errors::NotFoundError
@@ -6,13 +6,7 @@ RSpec.describe OllamaChat::Parsing do
6
6
  OllamaChat::Chat.new
7
7
  end
8
8
 
9
- before do
10
- stub_request(:get, %r(/api/tags\z)).
11
- to_return(status: 200, body: asset_json('api_tags.json'))
12
- stub_request(:post, %r(/api/show\z)).
13
- to_return(status: 200, body: asset_json('api_show.json'))
14
- chat
15
- end
9
+ connect_to_ollama_server
16
10
 
17
11
  describe '#parse_source' do
18
12
  it 'can parse HTML' do
@@ -5,13 +5,7 @@ RSpec.describe OllamaChat::SourceFetching do
5
5
  OllamaChat::Chat.new
6
6
  end
7
7
 
8
- before do
9
- stub_request(:get, %r(/api/tags\z)).
10
- to_return(status: 200, body: asset_json('api_tags.json'))
11
- stub_request(:post, %r(/api/show\z)).
12
- to_return(status: 200, body: asset_json('api_show.json'))
13
- allow(chat).to receive(:location).and_return(double(on?: false))
14
- end
8
+ connect_to_ollama_server
15
9
 
16
10
  it 'can import' do
17
11
  expect(chat.import('./spec/assets/example.html')).to start_with(<<~EOT)
@@ -42,13 +36,4 @@ RSpec.describe OllamaChat::SourceFetching do
42
36
  'This source was now embedded: ./spec/assets/example.html'
43
37
  )
44
38
  end
45
-
46
- it 'can search web' do
47
- stub_request(:get, "https://www.duckduckgo.com/html/?q=foo").
48
- with(headers: { 'Host'=>'www.duckduckgo.com' }).
49
- to_return(status: 200, body: asset_content('duckduckgo.html'), headers: {})
50
- expect(chat.search_web('foo').first.to_s).to eq(
51
- 'https://en.wikipedia.org/wiki/Foo_Fighters'
52
- )
53
- end
54
39
  end
@@ -33,6 +33,21 @@ RSpec.describe OllamaChat::Utils::Fetcher do
33
33
  end
34
34
  end
35
35
 
36
+ it 'can #get with headers' do
37
+ stub_request(:get, url).
38
+ with(headers: { 'Accept' => 'text/html' } | fetcher.headers).
39
+ to_return(
40
+ status: 200,
41
+ body: 'world',
42
+ headers: { 'Content-Type' => 'text/plain' },
43
+ )
44
+ fetcher.get(url, headers: { 'Accept' => 'text/html' }) do |tmp|
45
+ expect(tmp).to be_a Tempfile
46
+ expect(tmp.read).to eq 'world'
47
+ expect(tmp.content_type).to eq 'text/plain'
48
+ end
49
+ end
50
+
36
51
  it 'can #get without ssl peer verification' do
37
52
  fetcher = described_class.new(
38
53
  http_options: { ssl_verify_peer: false }
@@ -0,0 +1,29 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe OllamaChat::WebSearching do
4
+ let :chat do
5
+ OllamaChat::Chat.new
6
+ end
7
+
8
+ connect_to_ollama_server
9
+
10
+ it 'can search web with duckduckgo' do
11
+ expect(chat).to receive(:search_engine).and_return 'duckduckgo'
12
+ stub_request(:get, 'https://www.duckduckgo.com/html/?q=foo').
13
+ with(headers: { 'Host'=>'www.duckduckgo.com' }).
14
+ to_return(status: 200, body: asset_content('duckduckgo.html'), headers: {})
15
+ expect(chat.search_web('foo').first.to_s).to eq(
16
+ 'https://en.wikipedia.org/wiki/Foo_Fighters'
17
+ )
18
+ end
19
+
20
+ it 'can search web with searxng' do
21
+ expect(chat).to receive(:search_engine).and_return 'searxng'
22
+ stub_request(:get, 'http://localhost:8088/search?format=json&language=en&q=foo').
23
+ with(headers: { 'Host'=>'localhost:8088' }).
24
+ to_return(status: 200, body: asset_content('searxng.json'), headers: {})
25
+ expect(chat.search_web('foo').first.to_s).to eq(
26
+ 'https://en.wikipedia.org/wiki/Foo_Fighters'
27
+ )
28
+ end
29
+ end
data/spec/spec_helper.rb CHANGED
@@ -39,6 +39,18 @@ def asset_json(name)
39
39
  JSON(JSON(File.read(asset(name))))
40
40
  end
41
41
 
42
+ def connect_to_ollama_server(instantiate: true)
43
+ before do
44
+ stub_request(:get, %r(/api/tags\z)).
45
+ to_return(status: 200, body: asset_json('api_tags.json'))
46
+ stub_request(:post, %r(/api/show\z)).
47
+ to_return(status: 200, body: asset_json('api_show.json'))
48
+ stub_request(:get, %r(/api/version\z)).
49
+ to_return(status: 200, body: asset_json('api_version.json'))
50
+ instantiate and chat
51
+ end
52
+ end
53
+
42
54
  RSpec.configure do |config|
43
55
  config.before(:suite) do
44
56
  infobar.show = nil