ollama_chat 0.0.25 → 0.0.26

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: a08d4184578d406a8e5d02823cbd5fc0c1999591f86f715b99637b9a263ba7f4
4
- data.tar.gz: 2cdbb7c09d8de378fc58b292e4d2e29ba6849f3b9c3f1bb742ba658ec6b997e0
3
+ metadata.gz: f12c83374034666d30f5b8fdbe2e6b4f4b652ff9b418affee5117bc0d6e67fcc
4
+ data.tar.gz: f1ce7fca104f94ee159b1d6add90fcff3792d9e2a741d7d1f6f3cf3741646fd0
5
5
  SHA512:
6
- metadata.gz: da10d3bd76363f8856a0e35dfe927084374025c3e87a9e531d02ba07bcaa214e057a649ab9c3c46057947e651f8ca616344a1de30bcecc1d64fe4e8c13df3893
7
- data.tar.gz: c2944a6a328e5a1833d4becfe9842dbdd6b4d223bb36903b22254914d22ec19eadcc7942f0e4ba0d6a11d0fccfb4d41f3bf5624019901fb594e652aeacd70c21
6
+ metadata.gz: 2b6ec1e765aa5bf46200b5f308eea5b690674ebc296afcf240689385cabc91009da8145ee04b568296a7cff65d57c03e5c0c49fd38393a90abc9e659d6d4e9b2
7
+ data.tar.gz: c9a3db643d6efad021153f9c6cfad22f57696607354e21ca6a48dc5d3f454cf372327f31598542a1d70ad6e3fcdc4ca81b3a69c17e6c3b95dfc558a30aefc5d7
@@ -0,0 +1,25 @@
1
+ context do
2
+ namespace "lib" do
3
+ Dir['lib/**/*.rb'].each do |filename|
4
+ file filename, tags: 'lib'
5
+ end
6
+ end
7
+
8
+ namespace "spec" do
9
+ Dir['spec/**/*.rb'].each do |filename|
10
+ file filename, tags: 'spec'
11
+ end
12
+ end
13
+
14
+ file 'README.md', tags: 'documentation'
15
+
16
+ file '.contexts/yard.md', tags: [ 'yard', 'cheatsheet' ]
17
+
18
+ meta guidelins: <<~EOT
19
+ # Guidelines for creating YARD documentation
20
+
21
+ - Look into the file, with tags yard and cheatsheet for how comment ruby
22
+ constructs.
23
+ - In comments above initialize methods never omit @return
24
+ EOT
25
+ end
data/.contexts/full.rb CHANGED
@@ -15,6 +15,12 @@ context do
15
15
  end
16
16
  end
17
17
 
18
+ namespace "spec" do
19
+ Dir['spec/**/*.rb'].each do |filename|
20
+ file filename, tags: 'spec'
21
+ end
22
+ end
23
+
18
24
  file 'Rakefile', tags: 'gem_hadar'
19
25
 
20
26
  file 'README.md', tags: 'documentation'
data/.contexts/lib.rb CHANGED
@@ -17,6 +17,8 @@ context do
17
17
 
18
18
  file 'Rakefile', tags: 'gem_hadar'
19
19
 
20
+ file 'README.md', tags: 'documentation'
21
+
20
22
  meta ruby: RUBY_DESCRIPTION
21
23
 
22
24
  meta code_coverage: json('coverage/coverage_context.json')
data/.contexts/yard.md ADDED
@@ -0,0 +1,94 @@
1
+
2
+ # YARD Documentation Example
3
+
4
+ **You**, as an AI assistant, are tasked with generating only YARD documentation
5
+ comments for Ruby code, not executable code itself.
6
+
7
+ ## Your Documentation Responsibilities
8
+
9
+ When generating Ruby documentation, you must:
10
+
11
+ ### 1. **Generate Only Documentation Comments**
12
+ - Provide `#` prefixed comment blocks only
13
+ - Do not generate actual method bodies or class implementations
14
+ - Do not include executable code like `def`, `class`, `attr_reader`, etc.
15
+ - Focus solely on the documentation portions
16
+
17
+ ### 2. **Follow the Exact Structure from Example**
18
+ Here are the documentation comments from the Document class:
19
+
20
+ ```ruby
21
+ # Represents a generic document in a document management system.
22
+ # @example How to create a document
23
+ # document = Document.new('Hello World')
24
+ class Document
25
+ # @!attribute [r] title
26
+ # @return [String]
27
+ attr_reader :title
28
+
29
+ # @!attribute [w] description
30
+ # @return [String]
31
+ attr_writer :description
32
+
33
+ # @!attribute [rw] sections
34
+ # @api private
35
+ # @return [Array<Section>]
36
+ attr_accessor :sections
37
+
38
+ # Initializes a new Document instance.
39
+ # @note This method should be called with care.
40
+ #
41
+ # @param title [String] the title of the document
42
+ # @param description [String] the description of the document
43
+ # @param options [Hash] additional configuration options
44
+ # @option options [Boolean] :editable whether the document can be edited
45
+ # @yieldparam [String] content The content of the document.
46
+ # @yieldreturn [String] Returns a modified content.
47
+ #
48
+ # @raise [ArgumentError] if the title is nil
49
+ #
50
+ # @return [Document] a new Document instance
51
+ def initialize(title, description, options = {})
52
+ # Do NOT generate executable code
53
+ end
54
+
55
+ # Edits the document content.
56
+ #
57
+ # @overload edit(new_content)
58
+ # @param new_content [String] the new content for the document
59
+ # @return [Boolean] true if editing was successful, false otherwise
60
+ #
61
+ # @overload edit
62
+ # @yield Gives a block to process the current content.
63
+ # @yieldreturn [String] Returns the new content after processing.
64
+ # @return [Boolean] true if editing was successful, false otherwise
65
+ #
66
+ # @deprecated Use `modify` method instead.
67
+ def edit(new_content = nil)
68
+ # Do NOT generate executable code
69
+ end
70
+
71
+ # @todo Implement a proper save mechanism
72
+ def save
73
+ # Do NOT generate executable code
74
+ end
75
+
76
+ # Views the document
77
+ #
78
+ # @example Viewing the document title
79
+ # document.view_title #=> "Sample Document"
80
+ #
81
+ # @see #edit
82
+ # @return [String] the title of the document
83
+ def view_title
84
+ # Do NOT generate executable code
85
+ end
86
+ end
87
+ ```
88
+
89
+ ## Key Rule
90
+
91
+ **DO NOT GENERATE ANY EXECUTABLE CODE** - only documentation comments that
92
+ would be placed above actual Ruby methods and classes. The example shows what
93
+ the documentation comments should look like, not the actual executable Ruby
94
+ code.
data/.gitignore CHANGED
@@ -6,5 +6,6 @@
6
6
  Gemfile.lock
7
7
  corpus
8
8
  coverage
9
+ doc
9
10
  pkg
10
11
  tags
data/CHANGES.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changes
2
2
 
3
+ ## 2025-08-27 v0.0.26
4
+
5
+ - Enhanced `/last` command to support numeric argument, allowing users to
6
+ specify the number of messages to display
7
+ - Configured tests to protect environment variables by using `protect_env:
8
+ true` option and direct `ENV` manipulation
9
+ - Refactored spec helper with modularized `AssetHelpers`, `StubOllamaServer`,
10
+ and `ProtectEnvVars` modules for better organization
11
+ - Improved code clarity and added comprehensive documentation across multiple
12
+ modules including `OllamaChat`, `Chat`, `MessageList`, and others
13
+ - Added detailed class-level documentation for `OllamaChatConfig` with examples
14
+ - Included documentation for the `Parsing`, `Vim`, `MessageFormat`,
15
+ `KramdownANSI`, `Information`, `UserAgent`, and `History` modules
16
+ - Improved cache hit message formatting and wording for better user experience
17
+
3
18
  ## 2025-08-18 v0.0.25
4
19
 
5
20
  - Integrated `context_spook` gem as development dependency
data/README.md CHANGED
@@ -153,7 +153,7 @@ The following commands can be given inside the chat, if prefixed by a `/`:
153
153
  /stream toggle stream output
154
154
  /location toggle location submission
155
155
  /voice [change] toggle voice output or change the voice
156
- /last show the last system/assistant message
156
+ /last [n] show the last n / 1 system/assistant message
157
157
  /list [n] list the last n / all conversation exchanges
158
158
  /clear [what] clear what=messages|links|history|tags|all
159
159
  /clobber clear the conversation, links, and collection
@@ -177,6 +177,7 @@ The following commands can be given inside the chat, if prefixed by a `/`:
177
177
  /load filename load conversation messages
178
178
  /output filename save last response to filename
179
179
  /pipe command write last response to command's stdin
180
+ /vim insert the last message into a vim server
180
181
  /quit to quit
181
182
  /help to view this help
182
183
  ```
data/Rakefile CHANGED
@@ -21,7 +21,7 @@ GemHadar do
21
21
 
22
22
  test_dir 'spec'
23
23
  ignore '.*.sw[pon]', 'pkg', 'Gemfile.lock', '.AppleDouble', '.bundle',
24
- '.yardoc', 'tags', 'corpus', 'coverage', '/config/searxng/*'
24
+ '.yardoc', 'doc', 'tags', 'corpus', 'coverage', '/config/searxng/*'
25
25
 
26
26
  readme 'README.md'
27
27
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.25
1
+ 0.0.26
@@ -17,6 +17,20 @@ require 'xdg'
17
17
  require 'socket'
18
18
  require 'shellwords'
19
19
 
20
+ # A chat client for interacting with Ollama models through a terminal
21
+ # interface.
22
+ #
23
+ # The Chat class provides a complete command-line interface for chatting with
24
+ # language models via the Ollama API. It handles configuration management,
25
+ # message history, document processing, web searching, and various interactive
26
+ # features including voice output, markdown rendering, and embedding
27
+ # capabilities.
28
+ #
29
+ # @example Initializing a chat session
30
+ # chat = OllamaChat::Chat.new(argv: ['-m', 'llama3.1'])
31
+ #
32
+ # @example Starting an interactive chat
33
+ # chat.start
20
34
  class OllamaChat::Chat
21
35
  include Tins::GO
22
36
  include Term::ANSIColor
@@ -114,7 +128,6 @@ class OllamaChat::Chat
114
128
  # @return [Ollama::Client] the configured Ollama API client
115
129
  attr_reader :ollama
116
130
 
117
-
118
131
  # Returns the documents set for this object, initializing it lazily if needed.
119
132
  #
120
133
  # The documents set is memoized, meaning it will only be created once per
@@ -205,11 +218,12 @@ class OllamaChat::Chat
205
218
  end
206
219
  :next
207
220
  when %r(^/list(?:\s+(\d*))?$)
208
- last = 2 * $1.to_i if $1
209
- messages.list_conversation(last)
221
+ n = 2 * $1.to_i if $1
222
+ messages.list_conversation(n)
210
223
  :next
211
- when %r(^/last$)
212
- messages.show_last
224
+ when %r(^/last(?:\s+(\d*))?$)
225
+ n = $1.to_i if $1
226
+ messages.show_last(n)
213
227
  :next
214
228
  when %r(^/clear(?:\s+(messages|links|history|tags|all))?$)
215
229
  clean($1)
@@ -661,7 +675,6 @@ class OllamaChat::Chat
661
675
  #
662
676
  # @see fetch_source
663
677
  # @see embed_source
664
- # @see documents.clear
665
678
  def add_documents_from_argv(document_list)
666
679
  if document_list.any?(&:empty?)
667
680
  STDOUT.puts "Clearing collection #{bold{documents.collection}}."
@@ -1,20 +1,38 @@
1
+ # Module for handling document caching and retrieval using embedding
2
+ # similarity.
3
+ #
4
+ # This module provides methods to configure cache backends and manage document
5
+ # storage with semantic search capabilities. It integrates with Documentrix's
6
+ # document management system to enable efficient storage, retrieval, and
7
+ # similarity-based searching of documents using vector embeddings.
1
8
  module OllamaChat::DocumentCache
2
- # The document_cache_class method returns the cache class specified in the
3
- # configuration.
9
+ # Retrieves the cache class specified in the configuration.
4
10
  #
5
- # @return [ Class ] the cache class defined by the config.cache setting
11
+ # This method resolves the cache class name from the application's
12
+ # configuration to dynamically load the appropriate cache implementation.
13
+ #
14
+ # @return [Class] The cache class referenced by the configuration's cache
15
+ # setting.
16
+ # @raise [NameError] If the configured cache class name does not correspond
17
+ # to an existing constant.
6
18
  def document_cache_class
7
19
  Object.const_get(config.cache)
8
20
  end
9
21
 
10
- # The configure_cache method determines the appropriate cache class to use
11
- # for document storage.
12
- # It checks if the -M option was specified to use MemoryCache, otherwise it
13
- # attempts to use the configured cache class.
14
- # If an error occurs during this process, it falls back to using MemoryCache
15
- # and reports the error.
22
+ # Configures and returns the appropriate cache class based on command-line
23
+ # options.
24
+ #
25
+ # Determines which cache implementation to use based on command-line flags: -
26
+ # If the `-M` flag is set, uses {Documentrix::Documents::MemoryCache} -
27
+ # Otherwise, resolves and returns the cache class specified in configuration
28
+ #
29
+ # Falls back to {Documentrix::Documents::MemoryCache} if configuration
30
+ # resolution fails.
16
31
  #
17
- # @return [ Class ] the selected cache class to be used for document caching
32
+ # @return [Class] The selected cache class for document storage and
33
+ # retrieval.
34
+ # @raise [StandardError] If there is an error resolving the configured cache
35
+ # class, logs the error to standard error and falls back to MemoryCache.
18
36
  def configure_cache
19
37
  if @opts[?M]
20
38
  Documentrix::Documents::MemoryCache
@@ -1,3 +1,15 @@
1
+ # A class that handles chat responses and manages the flow of conversation
2
+ # between the user and Ollama models.
3
+ #
4
+ # This class is responsible for processing Ollama API responses, updating
5
+ # message history, displaying formatted output to the terminal, and managing
6
+ # voice synthesis for spoken responses. It acts as a handler for streaming
7
+ # responses and ensures proper formatting and display of both regular content
8
+ # and thinking annotations.
9
+ #
10
+ # @example Processing a chat response
11
+ # follow_chat = OllamaChat::FollowChat.new(chat: chat_instance, messages: message_list)
12
+ # follow_chat.call(response)
1
13
  class OllamaChat::FollowChat
2
14
  include Ollama
3
15
  include Ollama::Handlers::Concern
@@ -6,10 +18,13 @@ class OllamaChat::FollowChat
6
18
 
7
19
  # Initializes a new instance of OllamaChat::FollowChat.
8
20
  #
9
- # @param [OllamaChat::Chat] chat The chat object, which represents the conversation context.
10
- # @param [#to_a] messages A collection of message objects, representing the conversation history.
21
+ # @param [OllamaChat::Chat] chat The chat object, which represents the
22
+ # conversation context.
23
+ # @param [#to_a] messages A collection of message objects, representing the
24
+ # conversation history.
11
25
  # @param [String] voice (optional) to speek with if any.
12
- # @param [IO] output (optional) The output stream where terminal output should be printed. Defaults to STDOUT.
26
+ # @param [IO] output (optional) The output stream where terminal output
27
+ # should be printed. Defaults to STDOUT.
13
28
  #
14
29
  # @return [OllamaChat::FollowChat] A new instance of OllamaChat::FollowChat.
15
30
  def initialize(chat:, messages:, voice: nil, output: STDOUT)
@@ -23,7 +38,8 @@ class OllamaChat::FollowChat
23
38
 
24
39
  # Returns the conversation history (an array of message objects).
25
40
  #
26
- # @return [OllamaChat::MessageList<Ollama::Message>] The array of messages in the conversation.
41
+ # @return [OllamaChat::MessageList<Ollama::Message>] The array of messages in
42
+ # the conversation.
27
43
  attr_reader :messages
28
44
 
29
45
  # Invokes the chat flow based on the provided Ollama server response.
@@ -32,15 +48,18 @@ class OllamaChat::FollowChat
32
48
  # about the user input and the assistant's response.
33
49
  #
34
50
  # If the response indicates an assistant message, this method:
35
- # 1. Ensures that an assistant response exists in the message history (if not already present).
36
- # 2. Updates the last message with the new content and thinking (if applicable).
51
+ # 1. Ensures that an assistant response exists in the message history (if
52
+ # not already present).
53
+ # 2. Updates the last message with the new content and thinking (if
54
+ # applicable).
37
55
  # 3. Displays the formatted terminal output for the user.
38
56
  # 4. Outputs the voice response (if configured).
39
57
  #
40
58
  # Regardless of whether an assistant message is present, this method also
41
59
  # outputs evaluation statistics (if applicable).
42
60
  #
43
- # @param [Ollama::Response] response The parsed JSON response from the Ollama server.
61
+ # @param [Ollama::Response] response The parsed JSON response from the Ollama
62
+ # server.
44
63
  #
45
64
  # @return [OllamaChat::FollowChat] The current instance for method chaining.
46
65
  def call(response)
@@ -1,29 +1,77 @@
1
+ # A module that provides history management functionality for OllamaChat
2
+ # sessions.
3
+ #
4
+ # The History module encapsulates methods for initializing, saving, and
5
+ # clearing command-line history within the OllamaChat application. It handles
6
+ # persistence of user input history to a file and ensures that chat sessions
7
+ # can maintain state across invocations by loading previous command histories.
8
+ #
9
+ # @example Initializing chat history
10
+ # chat.init_chat_history
11
+ #
12
+ # @example Saving chat history
13
+ # chat.save_history
14
+ #
15
+ # @example Clearing chat history
16
+ # chat.clear_history
1
17
  module OllamaChat::History
2
- # Returns the full path of the chat history filename based on the
3
- # configuration.
18
+ # The chat_history_filename method constructs and returns the full file path
19
+ # for the chat history file.
20
+ #
21
+ # This method takes the configured chat history filename from the
22
+ # configuration and expands it to an absolute path using File.expand_path.
23
+ # This ensures that the returned path is fully qualified and can be used
24
+ # reliably for reading from or writing to the chat history file.
25
+ #
26
+ # @return [String] the absolute file path to the chat history file as
27
+ # specified in the configuration
4
28
  def chat_history_filename
5
29
  File.expand_path(config.chat_history_filename)
6
30
  end
7
31
 
8
- # Initializes the chat history by loading it from a file if it exists, and
9
- # then loads the history into Readline::HISTORY.
32
+ # The init_chat_history method initializes the chat session by loading
33
+ # previously saved command history from a file.
34
+ #
35
+ # This method checks for the existence of a chat history file and, if found,
36
+ # loads its contents into the Readline::HISTORY array. It clears the current
37
+ # history and replaces it with the saved history data. Any errors during the
38
+ # loading process are caught and logged as warnings, but do not interrupt the
39
+ # execution flow.
10
40
  def init_chat_history
11
41
  if File.exist?(chat_history_filename)
12
42
  File.open(chat_history_filename, ?r) do |history|
13
43
  history_data = JSON.load(history)
14
- clear_history
44
+ Readline::HISTORY.clear
15
45
  Readline::HISTORY.push(*history_data)
16
46
  end
17
47
  end
48
+ rescue => e
49
+ warn "Caught #{e.class} while loading #{chat_history_filename.inspect}: #{e}"
18
50
  end
19
51
 
20
- # Saves the current chat history to a file in JSON format.
52
+ # The save_history method persists the current command history to a file.
53
+ #
54
+ # This method serializes the Readline::HISTORY array into JSON format and
55
+ # writes it to the chat history filename. It handles potential errors during
56
+ # the write operation by catching exceptions and issuing a warning message.
21
57
  def save_history
22
58
  File.secure_write(chat_history_filename, JSON.dump(Readline::HISTORY))
59
+ rescue => e
60
+ warn "Caught #{e.class} while saving #{chat_history_filename.inspect}: #{e}"
23
61
  end
24
62
 
25
- # Clears all entries from Readline::HISTORY.
63
+ # The clear_history method clears the Readline history array and ensures that
64
+ # the chat history is saved afterwards.
65
+ #
66
+ # This method removes all entries from the Readline::HISTORY array,
67
+ # effectively clearing the command history maintained by the readline
68
+ # library. It then calls save_history to persist this cleared state to the
69
+ # configured history file. The method uses an ensure block to guarantee that
70
+ # save_history is called even if an exception occurs during the clearing
71
+ # process.
26
72
  def clear_history
27
73
  Readline::HISTORY.clear
74
+ ensure
75
+ save_history
28
76
  end
29
77
  end
@@ -1,3 +1,20 @@
1
+ # A module that provides information and user agent functionality for
2
+ # OllamaChat
3
+ #
4
+ # The Information module encapsulates methods for managing application
5
+ # identification, displaying version and configuration details, and handling
6
+ # command-line interface help messages. It includes user agent capabilities for
7
+ # HTTP requests and provides comprehensive information display features for
8
+ # chat sessions.
9
+ #
10
+ # @example Displaying application information
11
+ # chat.info
12
+ #
13
+ # @example Showing version details
14
+ # chat.version
15
+ #
16
+ # @example Displaying usage help
17
+ # chat.usage
1
18
  module OllamaChat::Information
2
19
  extend Tins::Concern
3
20
 
@@ -6,6 +23,20 @@ module OllamaChat::Information
6
23
  extend UserAgent
7
24
  end
8
25
 
26
+ # A module that provides user agent functionality for identifying the
27
+ # application.
28
+ #
29
+ # This module encapsulates methods for determining the application name and
30
+ # constructing a standardized user agent string that includes the application
31
+ # name and version. It is designed to be included in classes that need to
32
+ # provide identification information for HTTP requests or other
33
+ # communications.
34
+ #
35
+ # @example Accessing the program name
36
+ # UserAgent.progname # => "ollama_chat"
37
+ #
38
+ # @example Generating a user agent string
39
+ # UserAgent.user_agent # => "ollama_chat/0.0.25"
9
40
  module UserAgent
10
41
  # The progname method returns the name of the application.
11
42
  #
@@ -92,7 +123,7 @@ module OllamaChat::Information
92
123
  /stream toggle stream output
93
124
  /location toggle location submission
94
125
  /voice [change] toggle voice output or change the voice
95
- /last show the last system/assistant message
126
+ /last [n] show the last n / 1 system/assistant message
96
127
  /list [n] list the last n / all conversation exchanges
97
128
  /clear [what] clear what=messages|links|history|tags|all
98
129
  /clobber clear the conversation, links, and collection
@@ -1,3 +1,15 @@
1
+ # A module that provides Kramdown::ANSI styling configuration and parsing
2
+ # functionality for OllamaChat.
3
+ #
4
+ # This module handles the setup and application of ANSI styles for markdown
5
+ # rendering, allowing for customizable terminal output formatting. It manages
6
+ # the configuration of ANSI styles either from environment variables or falls
7
+ # back to default settings, and provides methods to parse content with the
8
+ # configured styling.
9
+ #
10
+ # @example Configuring custom ANSI styles via environment variable
11
+ # Set KRAMDOWN_ANSI_OLLAMA_CHAT_STYLES to a JSON object containing style
12
+ # definitions for customizing markdown output formatting in the terminal.
1
13
  module OllamaChat::KramdownANSI
2
14
  # The configure_kramdown_ansi_styles method sets up ANSI styling for
3
15
  # Kramdown::ANSI output by checking for specific environment variables and
@@ -1,3 +1,19 @@
1
+ # A module that provides formatting functionality for chat messages.
2
+ #
3
+ # The MessageFormat module encapsulates methods for determining message icons
4
+ # based on whether images are present, and for conditionally annotating content
5
+ # with thinking or talk indicators. It supports customizable formatting of
6
+ # message text for display in terminal interfaces.
7
+ #
8
+ # @example Using message_type to determine icon based on images
9
+ # message_type([]) # => "📨"
10
+ # message_type(["image"]) # => "📸"
11
+ #
12
+ # @example Annotating content with thinking indicator
13
+ # think_annotate { "Thinking..." } # => "💭\nThinking...\n" (when think is enabled)
14
+ #
15
+ # @example Annotating content with talk indicator
16
+ # talk_annotate { "Speaking..." } # => "💬\nSpeaking...\n" (when think is enabled)
1
17
  module OllamaChat::MessageFormat
2
18
  # The message_type method determines the appropriate message icon based on
3
19
  # whether images are present.
@@ -1,3 +1,33 @@
1
+ # A collection class for managing chat messages with support for system
2
+ # prompts, paged output, and conversation history.
3
+
4
+ # This class provides functionality for storing, retrieving, and displaying
5
+ # chat messages in a structured manner. It handles system prompts separately
6
+ # from regular user and assistant messages, supports pagination for displaying
7
+ # conversations, and offers methods for manipulating message history including
8
+ # clearing, loading, saving, and dropping exchanges. The class integrates with
9
+ # Kramdown::ANSI for formatted output and supports location information in
10
+ # system messages.
11
+
12
+ # @example Creating a new message list
13
+ # chat = OllamaChat::Chat.new
14
+ # messages = OllamaChat::MessageList.new(chat)
15
+ #
16
+ # @example Adding messages to the list
17
+ # messages << Ollama::Message.new(role: 'user', content: 'Hello')
18
+ # messages << Ollama::Message.new(role: 'assistant', content: 'Hi there!')
19
+ #
20
+ # @example Displaying conversation history
21
+ # messages.list_conversation(5) # Shows last 5 exchanges
22
+ #
23
+ # @example Clearing messages
24
+ # messages.clear # Removes all non-system messages
25
+ #
26
+ # @example Loading a saved conversation
27
+ # messages.load_conversation('conversation.json')
28
+ #
29
+ # @example Saving current conversation
30
+ # messages.save_conversation('my_conversation.json')
1
31
  class OllamaChat::MessageList
2
32
  include Term::ANSIColor
3
33
  include OllamaChat::MessageFormat
@@ -11,8 +41,20 @@ class OllamaChat::MessageList
11
41
  @messages = []
12
42
  end
13
43
 
44
+ # The system attribute reader returns the system prompt for the chat session.
45
+ #
46
+ # @attr_reader [ String, nil ] the current system prompt content or nil if not set
14
47
  attr_reader :system
15
48
 
49
+ # The messages attribute reader returns the messages set for this object,
50
+ # initializing it lazily if needed.
51
+ #
52
+ # The messages set is memoized, meaning it will only be created once per
53
+ # object instance and subsequent calls will return the same
54
+ # OllamaChat::MessageList instance.
55
+ #
56
+ # @attr_reader [OllamaChat::MessageList] A MessageList object containing all
57
+ # messages associated with this instance
16
58
  attr_reader :messages
17
59
 
18
60
  # Returns the number of messages stored in the message list.
@@ -111,11 +153,15 @@ class OllamaChat::MessageList
111
153
  # from the user. It uses a pager for output and returns the instance itself.
112
154
  #
113
155
  # @return [ OllamaChat::MessageList ] returns the instance of the class
114
- def show_last
115
- message = last
116
- !message || message.role == 'user' and return
156
+ def show_last(n = nil)
157
+ n ||= 1
158
+ messages = @messages.reject { |message| message.role == 'user' }
159
+ n = n.clamp(0..messages.size)
160
+ n <= 0 and return
117
161
  use_pager do |output|
118
- output.puts message_text_for(message)
162
+ messages[-n..-1].to_a.each do |message|
163
+ output.puts message_text_for(message)
164
+ end
119
165
  end
120
166
  self
121
167
  end
@@ -277,7 +323,8 @@ class OllamaChat::MessageList
277
323
  # If the output would exceed the terminal's line capacity, it pipes the content
278
324
  # through an appropriate pager command (like 'less' or 'more').
279
325
  #
280
- # @param block [Proc] A block that yields an IO object to write output to
326
+ # @yield A block that yields an IO object to write output to
327
+ # @yieldparam [IO] the IO object to write to
281
328
  def use_pager
282
329
  command = determine_pager_command
283
330
  output_buffer = StringIO.new
@@ -1,3 +1,15 @@
1
+ # A module that provides output functionality for chat messages.
2
+ #
3
+ # This module encapsulates methods for piping assistant responses to command
4
+ # standard input and writing assistant responses to files. It handles the
5
+ # mechanics of sending output to external processes or saving content to disk
6
+ # while providing appropriate error handling and user feedback.
7
+ #
8
+ # @example Piping a response to a command
9
+ # chat.pipe('cat > output.txt')
10
+ #
11
+ # @example Writing a response to a file
12
+ # chat.output('response.txt')
1
13
  module OllamaChat::MessageOutput
2
14
  # The pipe method forwards the last assistant message to a command's standard
3
15
  # input.