ollama_chat 0.0.56 → 0.0.57

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 683c0bf5fdb8756030c0c5b69767d95f8ae852094a0048cb61b4cf7166f6a045
4
- data.tar.gz: 8e7f9022cfd1e9c32f987b76196222d346100cd5ceaa6d59e6dc5c30257e5dbb
3
+ metadata.gz: '0812722ef6dcc9b968a058ad3e4d96a8944ba61aaf347e39b064881e67704c3c'
4
+ data.tar.gz: 03ceba63e04403a982eac23c0a1d5bbf9ff50512f83a721a2def8c5ed8ebec46
5
5
  SHA512:
6
- metadata.gz: 854af0ea07ced05e3f2f36741dd98592a2f6968e3307662e10c14bcb9a10b2168a1dde962de32f44e73719d177547cbccd8eee76c0554878a0de7ce2e1811772
7
- data.tar.gz: 86b71f7b0748be19d0f772213b1a21ea8c7f838296bcd48348076ef39372e0a0f07db20c59a1c1b56f8a7592d100993a7ffa6b6507b4febbbca2977f0375baff
6
+ metadata.gz: 14949a812f2040b5f4ec0fb767abcb8e41e8ff2f64af2502cc9278d8245f9794e1d7f9bcab0b1b99214c80aa135b1c9b68551a5d208356fa521f3fb36bb8e7f3
7
+ data.tar.gz: 44a2dfcccaa933286b5c0a0a93d6916e4bfd8e2af516d16d3524b4c26ffb76a59fd50557aef8262416fd00e7cb88e12d73fab653a6fda3c470f23f9be937d767
data/CHANGES.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-01-21 v0.0.57
4
+
5
+ - Introduce `OllamaChat::StateSelectors` module with `StateSelector` class for
6
+ managing configurable states
7
+ - Replace simple string-based document policy and think mode with
8
+ `StateSelector` objects
9
+ - Add `allow_empty` parameter to `StateSelector#initialize` method to allow
10
+ empty states in voice output
11
+ - Update `StateSelector#selected=` to conditionally validate states based on
12
+ `allow_empty?`
13
+ - Refactor voice handling to use `StateSelector` by replacing `@current_voice`
14
+ with `@voices` `StateSelector`
15
+ - Update `FollowChat` to use `@voices.selected` instead of `@current_voice` for
16
+ voice selection
17
+ - Simplify `change_voice` method in `dialog.rb` to delegate to `@voices.choose`
18
+ - Update voice display in `information.rb` to use `@voices.show` instead of raw
19
+ voice name
20
+ - Update configuration format to support nested `think` settings with `mode`
21
+ and `loud` sub-properties
22
+ - Modify command handlers to use `document_policy.choose` and
23
+ `think_mode.choose` instead of legacy methods
24
+ - Update `OllamaChat::Chat` initialization to use `setup_state_selectors`
25
+ method
26
+ - Refactor `OllamaChat::ThinkControl` to use new state selector system
27
+ - Update `OllamaChat::Parsing` to reference `@document_policy.selected` instead
28
+ of `@document_policy`
29
+ - Update default configuration file to use format with nested think settings
30
+ - Add proper `attr_reader` for `document_policy` and `think_mode` state
31
+ selectors
32
+ - Update help text to reference new state selector system
33
+ - Update `OllamaChat::Switches` to handle nested think configuration
34
+ - Add `OllamaChat::StateSelectors` to required files in `lib/ollama_chat.rb`
35
+
3
36
  ## 2026-01-17 v0.0.56
4
37
 
5
38
  - Updated `context_spook` dependency from version **1.4** to **1.5**
@@ -36,6 +36,7 @@ class OllamaChat::Chat
36
36
  include Term::ANSIColor
37
37
  include OllamaChat::DocumentCache
38
38
  include OllamaChat::Switches
39
+ include OllamaChat::StateSelectors
39
40
  include OllamaChat::ModelHandling
40
41
  include OllamaChat::Parsing
41
42
  include OllamaChat::SourceFetching
@@ -88,14 +89,13 @@ class OllamaChat::Chat
88
89
  @ollama_chat_config = OllamaChat::OllamaChatConfig.new(@opts[?f])
89
90
  self.config = @ollama_chat_config.config
90
91
  setup_switches(config)
92
+ setup_state_selectors(config)
91
93
  @ollama = connect_ollama
92
94
  if server_version.version < '0.9.0'.version
93
95
  raise ArgumentError, 'require ollama API version 0.9.0 or higher'
94
96
  end
95
- @document_policy = config.document_policy
96
97
  @model = choose_model(@opts[?m], config.model.name)
97
98
  @model_options = Ollama::Options[config.model.options]
98
- @think = config.think
99
99
  model_system = pull_model_unless_present(@model, @model_options)
100
100
  embedding_enabled.set(config.embedding.enabled && !@opts[?E])
101
101
  if @opts[?c]
@@ -111,7 +111,6 @@ class OllamaChat::Chat
111
111
  end
112
112
  @documents = setup_documents
113
113
  @cache = setup_cache
114
- @current_voice = config.voice.default
115
114
  @images = []
116
115
  @kramdown_ansi_styles = configure_kramdown_ansi_styles
117
116
  init_chat_history
@@ -120,6 +119,18 @@ class OllamaChat::Chat
120
119
  fix_config(e)
121
120
  end
122
121
 
122
+ # The document_policy reader returns the document policy selector for the chat session.
123
+ #
124
+ # @return [ OllamaChat::StateSelector ] the document policy selector object
125
+ # that manages the policy for handling document references in user text
126
+ attr_reader :document_policy
127
+
128
+ # The think_mode reader returns the think mode selector for the chat session.
129
+ #
130
+ # @return [ OllamaChat::StateSelector ] the think mode selector object
131
+ # that manages the thinking mode setting for the Ollama model interactions
132
+ attr_reader :think_mode
133
+
123
134
  # The debug method accesses the debug configuration setting.
124
135
  #
125
136
  # @return [TrueClass, FalseClass] the current debug mode status
@@ -304,10 +315,10 @@ class OllamaChat::Chat
304
315
  info
305
316
  :next
306
317
  when %r(^/document_policy$)
307
- choose_document_policy
318
+ document_policy.choose
308
319
  :next
309
320
  when %r(^/think$)
310
- choose_think_mode
321
+ think_mode.choose
311
322
  :next
312
323
  when %r(^/think_loud$)
313
324
  think_loud.toggle
@@ -385,9 +396,9 @@ class OllamaChat::Chat
385
396
  # the specified number of URLs. The processing approach varies based on the current
386
397
  # document policy and embedding status:
387
398
  #
388
- # - **Embedding mode**: When `@document_policy == 'embedding'` AND `@embedding.on?` is true,
399
+ # - **Embedding mode**: When `document_policy.selected == 'embedding'` AND `@embedding.on?` is true,
389
400
  # each result is embedded and the query is interpolated into the `web_embed` prompt.
390
- # - **Summarizing mode**: When `@document_policy == 'summarizing'`,
401
+ # - **Summarizing mode**: When `document_policy.selected == 'summarizing'`,
391
402
  # each result is summarized and both query and results are interpolated into the
392
403
  # `web_summarize` prompt.
393
404
  # - **Importing mode**: For all other cases, each result is imported and both query and
@@ -403,11 +414,11 @@ class OllamaChat::Chat
403
414
  # web('3', 'ruby programming tutorials')
404
415
  #
405
416
  # @example Web search with embedding policy
406
- # # With @document_policy == 'embedding' and @embedding.on?
417
+ # # With document_policy.selected == 'embedding' and @embedding.on?
407
418
  # # Processes results through embedding pipeline
408
419
  #
409
420
  # @example Web search with summarizing policy
410
- # # With @document_policy == 'summarizing'
421
+ # # With document_policy.selected == 'summarizing'
411
422
  # # Processes results through summarization pipeline
412
423
  #
413
424
  # @see #search_web
@@ -417,13 +428,13 @@ class OllamaChat::Chat
417
428
  # @see #summarize
418
429
  def web(count, query)
419
430
  urls = search_web(query, count.to_i) or return :next
420
- if @document_policy == 'embedding' && @embedding.on?
431
+ if document_policy.selected == 'embedding' && @embedding.on?
421
432
  prompt = config.prompts.web_embed
422
433
  urls.each do |url|
423
434
  fetch_source(url) { |url_io| embed_source(url_io, url) }
424
435
  end
425
436
  prompt.named_placeholders_interpolate({query:})
426
- elsif @document_policy == 'summarizing'
437
+ elsif document_policy.selected == 'summarizing'
427
438
  prompt = config.prompts.web_import
428
439
  results = urls.each_with_object('') do |url, content|
429
440
  summarize(url).full? do |c|
@@ -617,7 +628,7 @@ class OllamaChat::Chat
617
628
  handler = OllamaChat::FollowChat.new(
618
629
  chat: self,
619
630
  messages:,
620
- voice: (@current_voice if voice.on?)
631
+ voice: (@voices.selected if voice.on?)
621
632
  )
622
633
  begin
623
634
  retried = false
@@ -633,7 +644,7 @@ class OllamaChat::Chat
633
644
  if think? && !retried
634
645
  STDOUT.puts "#{bold('Error')}: in think mode, switch thinking off and retry."
635
646
  sleep 1
636
- @think = false
647
+ think_mode.selected = 'disabled'
637
648
  retried = true
638
649
  retry
639
650
  else
@@ -12,9 +12,6 @@
12
12
  #
13
13
  # @example Changing the system prompt
14
14
  # chat.change_system_prompt('default_prompt', system: '?sherlock')
15
- #
16
- # @example Choosing a document policy
17
- # chat.choose_document_policy
18
15
  module OllamaChat::Dialog
19
16
  # The model_with_size method formats a model's size for display
20
17
  # by creating a formatted string that includes the model name and its size
@@ -104,41 +101,6 @@ module OllamaChat::Dialog
104
101
  info
105
102
  end
106
103
 
107
- # The document_policy method sets the policy for handling document imports.
108
- #
109
- # @param value [ String ] the document policy to be set
110
- attr_writer :document_policy
111
-
112
- # The choose_document_policy method presents a menu to select a document policy.
113
- # It allows the user to choose from importing, embedding, summarizing, or
114
- # ignoring documents.
115
- # The method displays available policies and sets the selected policy as the
116
- # current document policy.
117
- # If no valid policy is found, it defaults to the first option.
118
- # After selection, it outputs the chosen policy and displays the current
119
- # configuration information.
120
- def choose_document_policy
121
- policies = %w[ importing embedding summarizing ignoring ].sort
122
- current = if policies.index(@document_policy)
123
- @document_policy
124
- elsif policies.index(config.document_policy)
125
- config.document_policy
126
- else
127
- policies.first
128
- end
129
- policies.unshift('[EXIT]')
130
- policy = OllamaChat::Utils::Chooser.choose(policies)
131
- case policy
132
- when nil, '[EXIT]'
133
- STDOUT.puts "Exiting chooser."
134
- policy = current
135
- end
136
- self.document_policy = policy
137
- ensure
138
- STDOUT.puts "Using document policy #{bold{@document_policy}}."
139
- info
140
- end
141
-
142
104
  # The change_system_prompt method allows the user to select or enter a new
143
105
  # system prompt for the chat session.
144
106
  # It provides an interactive chooser when multiple prompts match the given
@@ -204,8 +166,7 @@ module OllamaChat::Dialog
204
166
  #
205
167
  # @return [ String ] the full name of the chosen voice
206
168
  def change_voice
207
- chosen = OllamaChat::Utils::Chooser.choose(config.voice.list)
208
- @current_voice = chosen.full? || config.voice.default
169
+ @voices.choose
209
170
  end
210
171
 
211
172
  # The message_list method creates and returns a new MessageList instance
@@ -2,6 +2,15 @@ require 'const_conf'
2
2
  require 'pathname'
3
3
 
4
4
  module OllamaChat
5
+ # Environment configuration module for OllamaChat
6
+ #
7
+ # This module provides a structured way to manage environment variables and
8
+ # configuration settings for the OllamaChat application. It uses the
9
+ # ConstConf library to define and manage configuration parameters with
10
+ # default values, descriptions, and decoding logic.
11
+ #
12
+ # The module organizes configuration into logical sections including general
13
+ # settings, Ollama-specific configurations, and chat-specific options.
5
14
  module EnvConfig
6
15
  include ConstConf
7
16
 
@@ -99,15 +99,13 @@ module OllamaChat::Information
99
99
  end
100
100
  markdown.show
101
101
  stream.show
102
- think_show
102
+ think_mode.show
103
103
  think_loud.show
104
104
  location.show
105
105
  voice.show
106
- if @voice.on?
107
- STDOUT.puts " Using voice #{bold{@current_voice}} to speak."
108
- end
106
+ @voice.on? and @voices.show
109
107
  STDOUT.puts "Documents database cache is #{@documents.nil? ? 'n/a' : bold{@documents.cache.class}}"
110
- STDOUT.puts "Document policy for references in user text: #{bold{@document_policy}}"
108
+ STDOUT.puts "Document policy for references in user text: #{bold{document_policy}}"
111
109
  STDOUT.puts "Currently selected search engine is #{bold(search_engine)}."
112
110
  STDOUT.puts "Conversation length: #{bold(@messages.size.to_s)} message(s)."
113
111
  nil
@@ -144,7 +142,7 @@ module OllamaChat::Information
144
142
  /summarize [n] source summarize the source's content in n words
145
143
  /embedding toggle embedding paused or not
146
144
  /embed source embed the source's content
147
- /web [n] query query web & for n(=1) results (policy: #@document_policy)
145
+ /web [n] query query web & for n(=1) results (policy: #{document_policy})
148
146
  /links [clear] display (or clear) links used in the chat
149
147
  /save filename store conversation messages
150
148
  /load filename load conversation messages
@@ -41,8 +41,9 @@ voice:
41
41
  markdown: true
42
42
  stream: true
43
43
  document_policy: importing
44
- think: false
45
- think_loud: true
44
+ think:
45
+ mode: disabled
46
+ loud: true
46
47
  context:
47
48
  format: JSON
48
49
  embedding:
@@ -245,7 +245,7 @@ module OllamaChat::Parsing
245
245
  when 'image'
246
246
  add_image(images, source_io, source)
247
247
  when 'text', 'application', nil
248
- case @document_policy
248
+ case document_policy.selected
249
249
  when 'ignoring'
250
250
  nil
251
251
  when 'importing'
@@ -0,0 +1,146 @@
1
+ # A module that provides state selection functionality for OllamaChat.
2
+ #
3
+ # The StateSelectors module encapsulates the StateSelector class, which manages
4
+ # configurable states with selection and display capabilities. It is used to
5
+ # handle various settings in the chat application such as document policies and
6
+ # think modes, allowing users to dynamically configure
7
+ # different aspects of the chat session behavior.
8
+ module OllamaChat::StateSelectors
9
+ # A state selector that manages configurable states with selection and
10
+ # display capabilities.
11
+ class StateSelector
12
+ include Term::ANSIColor
13
+
14
+ # Initializes a new StateSelector with the given configuration.
15
+ #
16
+ # @param name [String] The name of the state selector for display purposes
17
+ # @param states [Array<String>] The list of valid states this selector can have
18
+ # @param default [String, nil] The default state to select (must be one of +states+)
19
+ # @param off [Array<String>, nil] The list of states that should be considered "off"
20
+ # @raise [ArgumentError] If +states+ is empty or +default+ is not in +states+
21
+ def initialize(name:, states:, default: nil, off: nil, allow_empty: false)
22
+ @name = name.to_s
23
+ @states = Set.new(states.map(&:to_s))
24
+ @allow_empty = allow_empty
25
+ unless allow_empty
26
+ @states.empty? and raise ArgumentError, 'states cannot be empty'
27
+ end
28
+ if default
29
+ @default = default.to_s
30
+ unless allow_empty?
31
+ @states.member?(@default) or raise ArgumentError,
32
+ "default has to be one of #{@states.to_a * ', '}."
33
+ end
34
+ @selected = @default
35
+ else
36
+ @selected = @states.first
37
+ end
38
+ @off = Array(off)
39
+ end
40
+
41
+ # The selected reader returns the currently selected state of the switch.
42
+ #
43
+ # @return [Object] the currently selected state value
44
+ attr_reader :selected
45
+
46
+ # The selected= method sets the selected state of the switch.
47
+ #
48
+ # @param value [Object] the value to be converted to a string and set as
49
+ # the selected state
50
+ #
51
+ # @raise [ArgumentError] if the provided value is not one of the valid states
52
+ def selected=(value)
53
+ value = value.to_s
54
+ unless allow_empty?
55
+ @states.member?(value) or raise ArgumentError,
56
+ "value has to be one of #{@states.to_a * ', '}."
57
+ end
58
+ @selected = value
59
+ end
60
+
61
+ # The allow_empty? method checks if the switch is allowed to be empty.
62
+ #
63
+ # @return [ TrueClass, FalseClass ] true if the switch is allowed to be
64
+ # empty, false otherwise
65
+ def allow_empty?
66
+ !!@allow_empty
67
+ end
68
+
69
+ # The off? method checks if the current state is in the off set.
70
+ #
71
+ # @return [ TrueClass, FalseClass ] true if the selected state is in the
72
+ # off set, false otherwise
73
+ def off?
74
+ @off.member?(@selected)
75
+ end
76
+
77
+ # The on? method checks if the switch is in the on state, returning true if
78
+ # it is enabled and false if it is disabled.
79
+ #
80
+ # @return [ TrueClass, FalseClass ] true if the switch is on, false if it
81
+ # is off
82
+ def on?
83
+ !off?
84
+ end
85
+
86
+ # The choose method presents a menu to select from available states.
87
+ #
88
+ # This method displays the available states to the user and allows them to
89
+ # select one. It handles the user's choice by updating the selected state
90
+ # or exiting the chooser if the user selects '[EXIT]' or cancels the selection.
91
+ #
92
+ # @return [ nil ] This method does not return a value; it updates the instance
93
+ # variable @selected based on user input.
94
+ def choose
95
+ states = @states + [ '[EXIT]' ]
96
+ case chosen = OllamaChat::Utils::Chooser.choose(states)
97
+ when '[EXIT]', nil
98
+ STDOUT.puts "Exiting chooser."
99
+ when
100
+ @selected = chosen
101
+ end
102
+ end
103
+
104
+ # The show method outputs the current value of the state selector.
105
+ #
106
+ # This method displays the name of the state selector along with its
107
+ # currently selected state in a formatted message to standard output.
108
+ def show
109
+ STDOUT.puts "#{@name} is #{bold(to_s)}."
110
+ end
111
+
112
+ # The to_s method returns the string representation of the selected state.
113
+ #
114
+ # @return [ String ] the string representation of the currently selected
115
+ # state
116
+ def to_s
117
+ @selected.to_s
118
+ end
119
+ end
120
+
121
+ # Sets up state selectors for document policy and think mode based on the
122
+ # provided configuration.
123
+ #
124
+ # @param config [ComplexConfig::Settings] the configuration object containing
125
+ # settings for document policy and think mode
126
+ def setup_state_selectors(config)
127
+ @document_policy = StateSelector.new(
128
+ name: 'Document policy',
129
+ default: config.document_policy,
130
+ states: %w[ embedding ignoring importing summarizing ],
131
+ off: %w[ ignoring ],
132
+ )
133
+ @think_mode = StateSelector.new(
134
+ name: 'Think mode',
135
+ default: config.think.mode,
136
+ states: %w[ enabled disabled low medium high ],
137
+ off: %w[ disabled ],
138
+ )
139
+ @voices = StateSelector.new(
140
+ name: 'Voice',
141
+ default: config.voice.default,
142
+ states: config.voice.list,
143
+ allow_empty: true
144
+ )
145
+ end
146
+ end
@@ -192,7 +192,7 @@ module OllamaChat::Switches
192
192
  )
193
193
 
194
194
  @think_loud = Switch.new(
195
- value: config.think_loud,
195
+ value: config.think.loud,
196
196
  msg: {
197
197
  true => "Thinking out loud, show thinking annotations.",
198
198
  false => "Thinking silently, don't show thinking annotations.",
@@ -5,52 +5,24 @@
5
5
  # thinking modes, checking the current state, and displaying the current
6
6
  # think mode status.
7
7
  module OllamaChat::ThinkControl
8
- # The think method returns the current state of the think mode.
8
+ # The think method returns the current think mode selection.
9
9
  #
10
- # @return [ true, false, String ] the think mode
11
- attr_reader :think
12
-
13
- # The choose_think_mode method presents a menu to select a think mode.
14
- #
15
- # This method displays available think modes to the user and sets the
16
- # selected mode as the current think mode for the chat session.
17
- def choose_think_mode
18
- think_modes = %w[ off on low medium high [EXIT] ]
19
- case chosen = OllamaChat::Utils::Chooser.choose(think_modes)
20
- when '[EXIT]', nil
21
- STDOUT.puts "Exiting chooser."
22
- when 'off'
23
- @think = false
24
- when 'on'
25
- @think = true
26
- when 'low', 'medium', 'high'
27
- @think = chosen
10
+ # @return [ String ] the selected think mode value
11
+ def think
12
+ if think_mode.off?
13
+ false
14
+ elsif think_mode.selected == 'enabled'
15
+ true
16
+ else
17
+ think_mode.selected
28
18
  end
29
19
  end
30
20
 
31
21
  # The think? method checks if the think mode is enabled.
32
22
  #
33
- # @return [ TrueClass, FalseClass ] true if think mode is enabled, false
34
- # otherwise
23
+ # @return [TrueClass, FalseClass] true if think mode is enabled, false otherwise
35
24
  def think?
36
- !!think
37
- end
38
-
39
- # The think_mode method returns the current think mode status as a string.
40
- #
41
- # @return [ String ] returns 'enabled' if think mode is true, the think mode
42
- # value if it's a string, or 'disabled' if think mode is false or nil
43
- def think_mode
44
- think == true ? 'enabled' : think || 'disabled'
45
- end
46
-
47
- # The think_show method displays the current think mode status.
48
- #
49
- # This method checks the current think mode setting and outputs a message
50
- # indicating whether think mode is enabled, disabled, or set to a specific
51
- # mode level (low, medium, high).
52
- def think_show
53
- STDOUT.puts "Think mode is #{bold(think_mode)}."
25
+ think_mode.on?
54
26
  end
55
27
 
56
28
  # The think_loud? method checks if both think mode and think loud mode are
@@ -1,6 +1,6 @@
1
1
  module OllamaChat
2
2
  # OllamaChat version
3
- VERSION = '0.0.56'
3
+ VERSION = '0.0.57'
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_chat.rb CHANGED
@@ -20,6 +20,7 @@ require 'ollama_chat/message_format'
20
20
  require 'ollama_chat/ollama_chat_config'
21
21
  require 'ollama_chat/follow_chat'
22
22
  require 'ollama_chat/switches'
23
+ require 'ollama_chat/state_selectors'
23
24
  require 'ollama_chat/message_list'
24
25
  require 'ollama_chat/model_handling'
25
26
  require 'ollama_chat/parsing'
data/ollama_chat.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: ollama_chat 0.0.56 ruby lib
2
+ # stub: ollama_chat 0.0.57 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ollama_chat".freeze
6
- s.version = "0.0.56".freeze
6
+ s.version = "0.0.57".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]
@@ -12,15 +12,15 @@ Gem::Specification.new do |s|
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, "ollama_chat_send".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/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/env_config.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/history.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/input_content.rb".freeze, "lib/ollama_chat/kramdown_ansi.rb".freeze, "lib/ollama_chat/message_editing.rb".freeze, "lib/ollama_chat/message_format.rb".freeze, "lib/ollama_chat/message_list.rb".freeze, "lib/ollama_chat/message_output.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/redis_cache.rb".freeze, "lib/ollama_chat/server_socket.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/think_control.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/vim.rb".freeze, "lib/ollama_chat/web_searching.rb".freeze]
16
- s.files = [".utilsrc".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "bin/ollama_chat".freeze, "bin/ollama_chat_send".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/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/env_config.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/history.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/input_content.rb".freeze, "lib/ollama_chat/kramdown_ansi.rb".freeze, "lib/ollama_chat/message_editing.rb".freeze, "lib/ollama_chat/message_format.rb".freeze, "lib/ollama_chat/message_list.rb".freeze, "lib/ollama_chat/message_output.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/redis_cache.rb".freeze, "lib/ollama_chat/server_socket.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/think_control.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/vim.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/example_with_quote.html".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/input_content_spec.rb".freeze, "spec/ollama_chat/kramdown_ansi_spec.rb".freeze, "spec/ollama_chat/message_editing_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/message_output_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/redis_cache_spec.rb".freeze, "spec/ollama_chat/server_socket_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/think_control_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/vim_spec.rb".freeze, "spec/ollama_chat/web_searching_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/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/env_config.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/history.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/input_content.rb".freeze, "lib/ollama_chat/kramdown_ansi.rb".freeze, "lib/ollama_chat/message_editing.rb".freeze, "lib/ollama_chat/message_format.rb".freeze, "lib/ollama_chat/message_list.rb".freeze, "lib/ollama_chat/message_output.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/redis_cache.rb".freeze, "lib/ollama_chat/server_socket.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/state_selectors.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/think_control.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/vim.rb".freeze, "lib/ollama_chat/web_searching.rb".freeze]
16
+ s.files = [".utilsrc".freeze, "CHANGES.md".freeze, "Gemfile".freeze, "README.md".freeze, "Rakefile".freeze, "bin/ollama_chat".freeze, "bin/ollama_chat_send".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/conversation.rb".freeze, "lib/ollama_chat/dialog.rb".freeze, "lib/ollama_chat/document_cache.rb".freeze, "lib/ollama_chat/env_config.rb".freeze, "lib/ollama_chat/follow_chat.rb".freeze, "lib/ollama_chat/history.rb".freeze, "lib/ollama_chat/information.rb".freeze, "lib/ollama_chat/input_content.rb".freeze, "lib/ollama_chat/kramdown_ansi.rb".freeze, "lib/ollama_chat/message_editing.rb".freeze, "lib/ollama_chat/message_format.rb".freeze, "lib/ollama_chat/message_list.rb".freeze, "lib/ollama_chat/message_output.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/redis_cache.rb".freeze, "lib/ollama_chat/server_socket.rb".freeze, "lib/ollama_chat/source_fetching.rb".freeze, "lib/ollama_chat/state_selectors.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/think_control.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/vim.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/example_with_quote.html".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/input_content_spec.rb".freeze, "spec/ollama_chat/kramdown_ansi_spec.rb".freeze, "spec/ollama_chat/message_editing_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/message_output_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/redis_cache_spec.rb".freeze, "spec/ollama_chat/server_socket_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/state_selectors_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/think_control_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/vim_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.2".freeze)
21
21
  s.rubygems_version = "4.0.3".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/input_content_spec.rb".freeze, "spec/ollama_chat/kramdown_ansi_spec.rb".freeze, "spec/ollama_chat/message_editing_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/message_output_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/redis_cache_spec.rb".freeze, "spec/ollama_chat/server_socket_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/think_control_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/vim_spec.rb".freeze, "spec/ollama_chat/web_searching_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/input_content_spec.rb".freeze, "spec/ollama_chat/kramdown_ansi_spec.rb".freeze, "spec/ollama_chat/message_editing_spec.rb".freeze, "spec/ollama_chat/message_list_spec.rb".freeze, "spec/ollama_chat/message_output_spec.rb".freeze, "spec/ollama_chat/model_handling_spec.rb".freeze, "spec/ollama_chat/parsing_spec.rb".freeze, "spec/ollama_chat/redis_cache_spec.rb".freeze, "spec/ollama_chat/server_socket_spec.rb".freeze, "spec/ollama_chat/source_fetching_spec.rb".freeze, "spec/ollama_chat/state_selectors_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/think_control_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/vim_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
 
@@ -1,12 +1,8 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::Chat, protect_env: true do
4
- use_default_config = -> a {
5
- a << '-f' << 'lib/ollama_chat/ollama_chat_config/default_config.yml'
6
- }
7
-
8
4
  let :argv do
9
- use_default_config.(%w[ -C test ])
5
+ chat_default_config(%w[ -C test ])
10
6
  end
11
7
 
12
8
  before do
@@ -134,7 +130,7 @@ describe OllamaChat::Chat, protect_env: true do
134
130
  end
135
131
 
136
132
  it 'returns :next when input is "/document_policy"' do
137
- expect(chat).to receive(:choose_document_policy)
133
+ expect_any_instance_of(OllamaChat::StateSelectors::StateSelector).to receive(:choose)
138
134
  expect(chat.handle_input("/document_policy")).to eq :next
139
135
  end
140
136
 
@@ -235,7 +231,7 @@ describe OllamaChat::Chat, protect_env: true do
235
231
  connect_to_ollama_server(instantiate: false)
236
232
 
237
233
  let :argv do
238
- use_default_config.(%w[ -C test -c ] << asset('conversation.json'))
234
+ chat_default_config(%w[ -C test -c ] << asset('conversation.json'))
239
235
  end
240
236
 
241
237
  it 'dispays the last exchange of the converstation' do
@@ -252,7 +248,7 @@ describe OllamaChat::Chat, protect_env: true do
252
248
  context 'with MemoryCache' do
253
249
 
254
250
  let :argv do
255
- use_default_config.(%w[ -M ])
251
+ chat_default_config(%w[ -M ])
256
252
  end
257
253
 
258
254
  it 'can use MemoryCache' do
@@ -274,7 +270,7 @@ describe OllamaChat::Chat, protect_env: true do
274
270
  connect_to_ollama_server(instantiate: false)
275
271
 
276
272
  let :argv do
277
- use_default_config.(%w[ -C test -D ] << asset('example.html'))
273
+ chat_default_config(%w[ -C test -D ] << asset('example.html'))
278
274
  end
279
275
 
280
276
  it 'Adds documents passed to app via -D option' do
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::Clipboard do
4
4
  let :chat do
5
- OllamaChat::Chat.new
5
+ OllamaChat::Chat.new argv: chat_default_config
6
6
  end
7
7
 
8
8
  connect_to_ollama_server
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::Information do
4
4
  let :chat do
5
- OllamaChat::Chat.new
5
+ OllamaChat::Chat.new argv: chat_default_config
6
6
  end
7
7
 
8
8
  connect_to_ollama_server
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::InputContent do
4
4
  let :chat do
5
- OllamaChat::Chat.new
5
+ OllamaChat::Chat.new argv: chat_default_config
6
6
  end
7
7
 
8
8
  connect_to_ollama_server
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::MessageEditing do
4
4
  let :chat do
5
- OllamaChat::Chat.new
5
+ OllamaChat::Chat.new argv: chat_default_config
6
6
  end
7
7
 
8
8
  connect_to_ollama_server
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::MessageOutput do
4
4
  let :chat do
5
- OllamaChat::Chat.new
5
+ OllamaChat::Chat.new argv: chat_default_config
6
6
  end
7
7
 
8
8
  connect_to_ollama_server
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::ModelHandling do
4
4
  let :chat do
5
- OllamaChat::Chat.new
5
+ OllamaChat::Chat.new argv: chat_default_config
6
6
  end
7
7
 
8
8
  connect_to_ollama_server
@@ -3,8 +3,8 @@ require 'pathname'
3
3
 
4
4
  describe OllamaChat::Parsing do
5
5
  let :chat do
6
- OllamaChat::Chat.new.tap do |chat|
7
- chat.document_policy = 'importing'
6
+ OllamaChat::Chat.new(argv: chat_default_config).tap do |chat|
7
+ chat.document_policy.selected = 'importing'
8
8
  end
9
9
  end
10
10
 
@@ -233,14 +233,14 @@ describe OllamaChat::Parsing do
233
233
 
234
234
  context 'document_policy' do
235
235
  it 'can be ignoring' do
236
- chat.document_policy = 'ignoring'
236
+ chat.document_policy.selected = 'ignoring'
237
237
  c = "see #{Dir.pwd}/spec/assets/example.html"
238
238
  content, = chat.parse_content(c, [])
239
239
  expect(content).to eq(c)
240
240
  end
241
241
 
242
242
  it 'can be importing' do
243
- chat.document_policy = 'importing'
243
+ chat.document_policy.selected = 'importing'
244
244
  c = "see #{Dir.pwd}/spec/assets/example.html"
245
245
  content, = chat.parse_content(c, [])
246
246
  expect(content).to include(<<~EOT)
@@ -253,7 +253,7 @@ describe OllamaChat::Parsing do
253
253
  end
254
254
 
255
255
  it 'can be embedding' do
256
- chat.document_policy = 'embedding'
256
+ chat.document_policy.selected = 'embedding'
257
257
  c = "see #{Dir.pwd}/spec/assets/example.html"
258
258
  expect(chat).to receive(:embed_source).with(
259
259
  kind_of(IO),
@@ -264,7 +264,7 @@ describe OllamaChat::Parsing do
264
264
  end
265
265
 
266
266
  it 'can be summarizing' do
267
- chat.document_policy = 'summarizing'
267
+ chat.document_policy.selected = 'summarizing'
268
268
  c = "see #{Dir.pwd}/spec/assets/example.html"
269
269
  content, = chat.parse_content(c, [])
270
270
  expect(content).to start_with(<<~EOT)
@@ -2,9 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::SourceFetching do
4
4
  let :chat do
5
- OllamaChat::Chat.new(
6
- argv: %w[ -f lib/ollama_chat/ollama_chat_config/default_config.yml ]
7
- )
5
+ OllamaChat::Chat.new(argv: chat_default_config)
8
6
  end
9
7
 
10
8
  connect_to_ollama_server
@@ -0,0 +1,193 @@
1
+ require 'spec_helper'
2
+
3
+ describe OllamaChat::StateSelectors::StateSelector do
4
+ let(:name) { 'Test Selector' }
5
+ let(:states) { %w[ enabled disabled low high ] }
6
+ let(:default) { 'enabled' }
7
+ let(:off) { %w[ disabled ] }
8
+
9
+ let(:selector) do
10
+ described_class.new(
11
+ name: name,
12
+ states: states,
13
+ default: default,
14
+ off: off
15
+ )
16
+ end
17
+
18
+ describe '#initialize' do
19
+ it 'creates a new StateSelector with provided parameters' do
20
+ expect(selector).to be_a described_class
21
+ end
22
+
23
+ it 'sets the name correctly' do
24
+ expect(selector.instance_variable_get(:@name)).to eq name
25
+ end
26
+
27
+ it 'sets the states correctly' do
28
+ expect(selector.instance_variable_get(:@states)).to eq Set.new(states)
29
+ end
30
+
31
+ it 'sets the default state' do
32
+ expect(selector.instance_variable_get(:@default)).to eq default
33
+ end
34
+
35
+ it 'sets the off states correctly' do
36
+ expect(selector.instance_variable_get(:@off)).to eq off
37
+ end
38
+
39
+ it 'sets the selected state to default' do
40
+ expect(selector.selected).to eq default
41
+ end
42
+
43
+ context 'with empty states' do
44
+ it 'raises ArgumentError when states are empty' do
45
+ expect {
46
+ described_class.new(name: 'Test', states: [])
47
+ }.to raise_error(ArgumentError, 'states cannot be empty')
48
+ end
49
+ end
50
+
51
+ context 'with invalid default' do
52
+ it 'raises ArgumentError when default is not in states' do
53
+ expect {
54
+ described_class.new(name: 'Test', states: %w[ a b ], default: 'c')
55
+ }.to raise_error(ArgumentError, 'default has to be one of a, b.')
56
+ end
57
+ end
58
+ end
59
+
60
+ describe '#selected' do
61
+ it 'returns the currently selected state' do
62
+ expect(selector.selected).to eq default
63
+ end
64
+ end
65
+
66
+ describe '#selected=' do
67
+ it 'sets the selected state to a valid value' do
68
+ selector.selected = 'low'
69
+ expect(selector.selected).to eq 'low'
70
+ end
71
+
72
+ it 'raises ArgumentError when setting invalid state' do
73
+ expect {
74
+ selector.selected = 'invalid'
75
+ }.to raise_error(ArgumentError, 'value has to be one of enabled, disabled, low, high.')
76
+ end
77
+ end
78
+
79
+ describe '#allow_empty?' do
80
+ it 'returns false by default' do
81
+ expect(selector.allow_empty?).to be false
82
+ end
83
+
84
+ context 'when allow_empty is true' do
85
+ let(:selector) do
86
+ described_class.new(
87
+ name: name,
88
+ states: states,
89
+ default: nil,
90
+ allow_empty: true
91
+ )
92
+ end
93
+
94
+ it 'returns true when allow_empty is set' do
95
+ expect(selector.allow_empty?).to be true
96
+ end
97
+ end
98
+ end
99
+
100
+ describe '#off?' do
101
+ it 'returns true when selected state is in off set' do
102
+ selector.selected = 'disabled'
103
+ expect(selector.off?).to be true
104
+ end
105
+
106
+ it 'returns false when selected state is not in off set' do
107
+ selector.selected = 'enabled'
108
+ expect(selector.off?).to be false
109
+ end
110
+ end
111
+
112
+ describe '#on?' do
113
+ it 'returns true when selected state is not in off set' do
114
+ selector.selected = 'enabled'
115
+ expect(selector.on?).to be true
116
+ end
117
+
118
+ it 'returns false when selected state is in off set' do
119
+ selector.selected = 'disabled'
120
+ expect(selector.on?).to be false
121
+ end
122
+ end
123
+
124
+ describe '#choose' do
125
+ it 'allows user to select a state from available options' do
126
+ # Mock the chooser to return a specific choice
127
+ expect(OllamaChat::Utils::Chooser).to receive(:choose).with(
128
+ %w[ enabled disabled low high [EXIT] ]
129
+ ).and_return('low')
130
+
131
+ selector.choose
132
+ expect(selector.selected).to eq 'low'
133
+ end
134
+
135
+ it 'exits when user selects [EXIT]' do
136
+ expect(OllamaChat::Utils::Chooser).to receive(:choose).and_return('[EXIT]')
137
+
138
+ selector.choose
139
+ expect(selector.selected).to eq default
140
+ end
141
+
142
+ it 'exits when user cancels selection' do
143
+ expect(OllamaChat::Utils::Chooser).to receive(:choose).and_return(nil)
144
+
145
+ selector.choose
146
+ expect(selector.selected).to eq default
147
+ end
148
+ end
149
+
150
+ describe '#show' do
151
+ it 'outputs the current state to stdout' do
152
+ expect(STDOUT).to receive(:puts).with(/Test Selector is .*?enabled.*?\./)
153
+ selector.show
154
+ end
155
+ end
156
+
157
+ describe '#to_s' do
158
+ it 'returns the string representation of the selected state' do
159
+ expect(selector.to_s).to eq default
160
+ end
161
+
162
+ it 'returns the string representation after changing state' do
163
+ selector.selected = 'low'
164
+ expect(selector.to_s).to eq 'low'
165
+ end
166
+ end
167
+
168
+ describe 'with allow_empty true' do
169
+ let(:selector) do
170
+ described_class.new(
171
+ name: 'Empty Selector',
172
+ states: %w[ a b c ],
173
+ default: nil,
174
+ allow_empty: true
175
+ )
176
+ end
177
+
178
+ it 'allows setting nil as selected state' do
179
+ selector.selected = nil
180
+ expect(selector.selected).to eq ""
181
+ end
182
+
183
+ it 'allows empty state when allow_empty is true' do
184
+ expect(selector.allow_empty?).to be true
185
+ end
186
+
187
+ it 'raises no error when setting invalid state' do
188
+ expect {
189
+ selector.selected = 'invalid'
190
+ }.not_to raise_error
191
+ end
192
+ end
193
+ end
@@ -2,153 +2,93 @@ require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::ThinkControl do
4
4
  let :chat do
5
- OllamaChat::Chat.new(
6
- argv: %w[ -f lib/ollama_chat/ollama_chat_config/default_config.yml ]
7
- )
5
+ OllamaChat::Chat.new(argv: chat_default_config)
8
6
  end
9
7
 
10
8
  connect_to_ollama_server
11
9
 
12
10
  describe '#think' do
13
- it 'returns the current think mode state' do
11
+ it 'returns false when the think mode selector is off' do
12
+ chat.think_mode.selected = 'disabled'
14
13
  expect(chat.think).to be false
15
- chat.instance_variable_set(:@think, true)
14
+ end
15
+
16
+ it 'returns true when the think mode selector is enabled' do
17
+ chat.think_mode.selected = 'enabled'
16
18
  expect(chat.think).to be true
17
- chat.instance_variable_set(:@think, false)
18
- expect(chat.think).to be false
19
- chat.instance_variable_set(:@think, 'low')
19
+ end
20
+
21
+ it 'returns the selected value when it is not “enabled”' do
22
+ chat.think_mode.selected = 'low'
20
23
  expect(chat.think).to eq 'low'
21
24
  end
22
25
  end
23
26
 
24
27
  describe '#think?' do
25
- it 'returns true when think mode is enabled (boolean true)' do
26
- chat.instance_variable_set(:@think, true)
28
+ it 'returns true when the think mode selector is on' do
29
+ chat.think_mode.selected = 'enabled'
27
30
  expect(chat.think?).to be true
28
31
  end
29
32
 
30
- it 'returns true when think mode is enabled (string value)' do
31
- chat.instance_variable_set(:@think, 'high')
33
+ it 'returns true when the think mode selector is on but the value is a string' do
34
+ chat.think_mode.selected = 'high'
32
35
  expect(chat.think?).to be true
33
36
  end
34
37
 
35
- it 'returns false when think mode is disabled (boolean false)' do
36
- chat.instance_variable_set(:@think, false)
37
- expect(chat.think?).to be false
38
- end
39
-
40
- it 'returns false when think mode is nil' do
41
- chat.instance_variable_set(:@think, nil)
38
+ it 'returns false when the think mode selector is off' do
39
+ chat.think_mode.selected = 'disabled'
42
40
  expect(chat.think?).to be false
43
41
  end
44
42
  end
45
43
 
46
44
  describe '#think_mode' do
47
- it 'returns "enabled" when think is true' do
48
- chat.instance_variable_set(:@think, true)
49
- expect(chat.think_mode).to eq 'enabled'
45
+ it 'exposes a StateSelector instance' do
46
+ expect(chat.think_mode).to be_a OllamaChat::StateSelectors::StateSelector
50
47
  end
51
48
 
52
- it 'returns the think value when it is a string' do
53
- chat.instance_variable_set(:@think, 'medium')
54
- expect(chat.think_mode).to eq 'medium'
55
- end
56
-
57
- it 'returns "disabled" when think is false' do
58
- chat.instance_variable_set(:@think, false)
59
- expect(chat.think_mode).to eq 'disabled'
60
- end
61
-
62
- it 'returns "disabled" when think is nil' do
63
- chat.instance_variable_set(:@think, nil)
64
- expect(chat.think_mode).to eq 'disabled'
65
- end
66
- end
67
-
68
- describe '#think_show' do
69
- it 'displays the current think mode status' do
70
- chat.instance_variable_set(:@think, true)
71
- expect(STDOUT).to receive(:puts).with(/Think mode is \e\[1menabled\e\[0m\./)
72
- chat.think_show
73
- end
74
-
75
- it 'displays the think mode level when set to string' do
76
- chat.instance_variable_set(:@think, 'high')
77
- expect(STDOUT).to receive(:puts).with(/Think mode is \e\[1mhigh\e\[0m\./)
78
- chat.think_show
79
- end
80
-
81
- it 'displays "disabled" when think is false' do
82
- chat.instance_variable_set(:@think, false)
83
- expect(STDOUT).to receive(:puts).with(/Think mode is \e\[1mdisabled\e\[0m\./)
84
- chat.think_show
85
- end
86
-
87
- it 'displays "disabled" when think is nil' do
88
- chat.instance_variable_set(:@think, nil)
89
- expect(STDOUT).to receive(:puts).with(/Think mode is \e\[1mdisabled\e\[0m\./)
90
- chat.think_show
49
+ it 'has the correct default selection (disabled)' do
50
+ expect(chat.think_mode.selected).to eq 'disabled'
91
51
  end
92
52
  end
93
53
 
94
54
  describe '#think_loud?' do
95
- it 'returns false when think is disabled' do
96
- chat.instance_variable_set(:@think, false)
55
+ it 'returns false when the think mode selector is off' do
56
+ chat.think_mode.selected = 'disabled'
97
57
  expect(chat.think_loud?).to be false
98
58
  end
99
59
 
100
- it 'returns false when think_loud is off' do
101
- chat.instance_variable_set(:@think, true)
60
+ it 'returns false when the think_loud switch is off' do
61
+ chat.think_mode.selected = 'enabled'
102
62
  allow(chat).to receive(:think_loud).and_return(double(on?: false))
103
63
  expect(chat.think_loud?).to be false
104
64
  end
105
65
 
106
- it 'returns true when both think and think_loud are enabled' do
107
- chat.instance_variable_set(:@think, true)
66
+ it 'returns true when both the think mode selector and think_loud switch are on' do
67
+ chat.think_mode.selected = 'enabled'
108
68
  allow(chat).to receive(:think_loud).and_return(double(on?: true))
109
69
  expect(chat.think_loud?).to be true
110
70
  end
111
71
  end
112
72
 
113
- describe '#choose_think_mode' do
114
- it 'can select "off" mode' do
115
- expect(OllamaChat::Utils::Chooser).to receive(:choose).and_return('off')
116
- chat.choose_think_mode
117
- expect(chat.think).to be false
73
+ describe '#think_mode.show' do
74
+ it 'prints the current think mode in bold' do
75
+ chat.think_mode.selected = 'high'
76
+ expect(STDOUT).to receive(:puts).with(/Think mode is \e\[1mhigh\e\[0m/)
77
+ chat.think_mode.show
118
78
  end
119
79
 
120
- it 'can select "on" mode' do
121
- expect(OllamaChat::Utils::Chooser).to receive(:choose).and_return('on')
122
- chat.choose_think_mode
123
- expect(chat.think).to be true
80
+ it 'prints “disabled” when the selector is off' do
81
+ chat.think_mode.selected = 'disabled'
82
+ expect(STDOUT).to receive(:puts).with(/Think mode is \e\[1mdisabled\e\[0m/)
83
+ chat.think_mode.show
124
84
  end
85
+ end
125
86
 
126
- it 'can select "low" mode' do
87
+ describe '#think_mode.choose' do
88
+ it 'updates the selector based on the user choice' do
127
89
  expect(OllamaChat::Utils::Chooser).to receive(:choose).and_return('low')
128
- chat.choose_think_mode
129
- expect(chat.think).to eq 'low'
130
- end
131
-
132
- it 'can select "medium" mode' do
133
- expect(OllamaChat::Utils::Chooser).to receive(:choose).and_return('medium')
134
- chat.choose_think_mode
135
- expect(chat.think).to eq 'medium'
136
- end
137
-
138
- it 'can select "high" mode' do
139
- expect(OllamaChat::Utils::Chooser).to receive(:choose).and_return('high')
140
- chat.choose_think_mode
141
- expect(chat.think).to eq 'high'
142
- end
143
-
144
- it 'can exit selection' do
145
- expect(OllamaChat::Utils::Chooser).to receive(:choose).and_return('[EXIT]')
146
- expect { chat.choose_think_mode }.not_to change { chat.think }
147
- end
148
-
149
- it 'can handle nil selection' do
150
- expect(OllamaChat::Utils::Chooser).to receive(:choose).and_return(nil)
151
- expect { chat.choose_think_mode }.not_to change { chat.think }
90
+ chat.think_mode.choose
91
+ expect(chat.think_mode.selected).to eq 'low'
152
92
  end
153
93
  end
154
94
  end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe OllamaChat::WebSearching do
4
4
  let :chat do
5
- OllamaChat::Chat.new
5
+ OllamaChat::Chat.new(argv: chat_default_config)
6
6
  end
7
7
 
8
8
  connect_to_ollama_server
data/spec/spec_helper.rb CHANGED
@@ -86,6 +86,10 @@ module AssetHelpers
86
86
  end
87
87
  end
88
88
 
89
+ def chat_default_config(a = [])
90
+ a + %w[ -f lib/ollama_chat/ollama_chat_config/default_config.yml ]
91
+ end
92
+
89
93
  # A module that provides functionality for stubbing Ollama server responses.
90
94
  #
91
95
  # The StubOllamaServer module enables developers to simulate Ollama API
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ollama_chat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.56
4
+ version: 0.0.57
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
@@ -430,6 +430,7 @@ extra_rdoc_files:
430
430
  - lib/ollama_chat/redis_cache.rb
431
431
  - lib/ollama_chat/server_socket.rb
432
432
  - lib/ollama_chat/source_fetching.rb
433
+ - lib/ollama_chat/state_selectors.rb
433
434
  - lib/ollama_chat/switches.rb
434
435
  - lib/ollama_chat/think_control.rb
435
436
  - lib/ollama_chat/utils.rb
@@ -473,6 +474,7 @@ files:
473
474
  - lib/ollama_chat/redis_cache.rb
474
475
  - lib/ollama_chat/server_socket.rb
475
476
  - lib/ollama_chat/source_fetching.rb
477
+ - lib/ollama_chat/state_selectors.rb
476
478
  - lib/ollama_chat/switches.rb
477
479
  - lib/ollama_chat/think_control.rb
478
480
  - lib/ollama_chat/utils.rb
@@ -516,6 +518,7 @@ files:
516
518
  - spec/ollama_chat/redis_cache_spec.rb
517
519
  - spec/ollama_chat/server_socket_spec.rb
518
520
  - spec/ollama_chat/source_fetching_spec.rb
521
+ - spec/ollama_chat/state_selectors_spec.rb
519
522
  - spec/ollama_chat/switches_spec.rb
520
523
  - spec/ollama_chat/think_control_spec.rb
521
524
  - spec/ollama_chat/utils/cache_fetcher_spec.rb
@@ -566,6 +569,7 @@ test_files:
566
569
  - spec/ollama_chat/redis_cache_spec.rb
567
570
  - spec/ollama_chat/server_socket_spec.rb
568
571
  - spec/ollama_chat/source_fetching_spec.rb
572
+ - spec/ollama_chat/state_selectors_spec.rb
569
573
  - spec/ollama_chat/switches_spec.rb
570
574
  - spec/ollama_chat/think_control_spec.rb
571
575
  - spec/ollama_chat/utils/cache_fetcher_spec.rb