ollama_chat 0.0.59 → 0.0.60

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: 98fa6fed72170e4aa21b04c8a66ba443942ed66cb9b2eb380708029a2fd592f5
4
- data.tar.gz: 40ed71dcd2a5770289dc1d1e5e29f44679b436584b8ce24ed6fa4756c8c694f6
3
+ metadata.gz: 6fe8b2e7b1c16fa9ca743e0392899cf7532c53d18967b489e161be5a31aede29
4
+ data.tar.gz: 9d90e8a784c9f867ca2c09f87fe790775bbb4ba40cff402c3881d1ce699f7a98
5
5
  SHA512:
6
- metadata.gz: b64ad829de42272883cfdfad370cc2a34a97d4b68efe957019a05f07e8b6b8ff0aa1a3d80711427da117c58bfbb4d39265921bcfe228bbac7805a7c4fa1a8725
7
- data.tar.gz: 3d91f987a19b7b387ca2f21edb7e0b3643c79e7f5c983c160d441a08415b47c5267e74f86f1bd30f3881c5001b4916fd9555d461f733b3f9d0278fb0e0b9a895
6
+ metadata.gz: d328237ec64de21983afcea8f61d0a1cf41d694d8bf7d215d46d68c2eccc6795a99a1e1ebec396a1713db2ba5adbd6d6ac5a0a96b8a287c49534780bfb54cf10
7
+ data.tar.gz: 83bc6f0373224e4220a889798a2265f8f45ef9991537287fdb8503a29a6f092a0abe6621dbb8c191fa5f96ae09f4f53400bc665c8768ec980d37baa6b83c8aa4
data/CHANGES.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-02-06 v0.0.60
4
+
5
+ ### New Features
6
+ - Added `OllamaChat::LocationHandling` module for location data management
7
+ - Introduced `get_location`, `file_context`, and `directory_structure` tools
8
+ - Implemented recursive directory traversal with depth limiting and hidden file
9
+ skipping
10
+
11
+ ### Tool Enhancements
12
+ - Enhanced tool calling system to pass `chat: @chat` to tool execution
13
+ - Updated `@enabled_tools` initialization to use default tool configurations
14
+ - Implemented automatic tool class instantiation in the `register` method
15
+ - Configured new tools to be disabled by default in `default_config.yml`
16
+
17
+ ### Technical Improvements
18
+ - Added dynamic format conversion with `send("to_#{format.downcase}")`
19
+ - Updated `MessageList#at_location` to use the new location handling approach
20
+ - Enhanced `list_tools` output with visual enabled/disabled indicators
21
+ - Integrated location data into system prompts via `location_description`
22
+ method
23
+
24
+ ### Documentation & Testing
25
+ - Added comprehensive YARD documentation for location handling and tools
26
+ - Added new tool files and test files to gemspec's `s.files`, `s.test_files`,
27
+ and `s.extra_rdoc_files`
28
+ - Added comprehensive test coverage for new tools and location handling
29
+
30
+ ### Configuration
31
+ - Updated default tool configuration to use `config.tools.to_h.map` for tool
32
+ registration
33
+ - Configured new tools to be disabled by default in `default_config.yml`
34
+
35
+ ### Code Structure
36
+ - Updated gemspec to include new files and test files
37
+ - Refactored `InputContent` to use dynamic format conversion
38
+ - Enhanced `FollowChat` to pass chat instance to tool execution
39
+ - Updated `MessageList#at_location` to use new location handling approach
40
+
3
41
  ## 2026-02-05 v0.0.59
4
42
 
5
43
  ### New Features
@@ -53,6 +53,7 @@ class OllamaChat::Chat
53
53
  include OllamaChat::Conversation
54
54
  include OllamaChat::InputContent
55
55
  include OllamaChat::MessageEditing
56
+ include OllamaChat::LocationHandling
56
57
  include OllamaChat::ToolCalling
57
58
 
58
59
  # Initializes a new OllamaChat::Chat instance with the given command-line
@@ -113,7 +114,7 @@ class OllamaChat::Chat
113
114
  @kramdown_ansi_styles = configure_kramdown_ansi_styles
114
115
  init_chat_history
115
116
  @opts[?S] and init_server_socket
116
- @enabled_tools = []
117
+ @enabled_tools = config.tools.to_h.map { |n, v| n.to_s if v[:default] }.compact
117
118
  @tool_call_results = {}
118
119
  rescue ComplexConfig::AttributeMissing, ComplexConfig::ConfigurationSyntaxError => e
119
120
  fix_config(e)
@@ -103,7 +103,7 @@ class OllamaChat::FollowChat
103
103
  response.message.tool_calls.each do |tool_call|
104
104
  name = tool_call.function.name
105
105
  @chat.tool_call_results[name] = OllamaChat::Tools.registered[name].
106
- execute(tool_call, config: @chat.config)
106
+ execute(tool_call, chat: @chat, config: @chat.config)
107
107
  end
108
108
  end
109
109
 
@@ -92,7 +92,8 @@ module OllamaChat::InputContent
92
92
  end.to_json
93
93
  else
94
94
  if context_filename = choose_filename('.contexts/*.rb')
95
- ContextSpook.generate_context(context_filename, verbose: true, format:).to_json
95
+ ContextSpook.generate_context(context_filename, verbose: true, format:).
96
+ send("to_#{format.downcase}")
96
97
  end
97
98
  end
98
99
  end
@@ -0,0 +1,45 @@
1
+ # A module that provides location handling functionality for OllamaChat.
2
+ #
3
+ # The LocationHandling module encapsulates methods for managing location
4
+ # information, including generating location data and creating location
5
+ # descriptions for use in chat sessions. It integrates with the application's
6
+ # configuration to provide contextual location information to language models.
7
+ #
8
+ # @example Generating location information
9
+ # chat.location_data # => { location_name: "New York", location_decimal_degrees: "40.7128, -74.0060", localtime: "2023-10-15T10:30:00Z", units: "metric" }
10
+ # chat.location_description # => "Current location: New York (40.7128, -74.0060) at 2023-10-15T10:30:00Z in metric units"
11
+ #
12
+ # @see OllamaChat::Chat
13
+ module OllamaChat::LocationHandling
14
+ # Generates a location description string formatted with the current location
15
+ # data.
16
+ #
17
+ # This method creates a formatted string containing location information
18
+ # including name, coordinates, local time, and units, using the configured
19
+ # location prompt template.
20
+ #
21
+ # @return [String] a formatted location description string
22
+ # @see #location_data
23
+ def location_description
24
+ config.prompts.location % location_data
25
+ end
26
+
27
+ # Generates a hash containing current location data.
28
+ #
29
+ # This method collects and returns structured location information including
30
+ # the location name, decimal degrees coordinates, local time, and units.
31
+ #
32
+ # @return [Hash] a hash containing location data with keys:
33
+ # - location_name: The name of the location
34
+ # - location_decimal_degrees: Comma-separated decimal degrees coordinates
35
+ # - localtime: Current local time in ISO 8601 format
36
+ # - units: The unit system (metric, imperial, etc.)
37
+ def location_data
38
+ {
39
+ location_name: config.location.name,
40
+ location_decimal_degrees: config.location.decimal_degrees * ', ',
41
+ localtime: Time.now.iso8601,
42
+ units: config.location.units,
43
+ }
44
+ end
45
+ end
@@ -281,15 +281,7 @@ class OllamaChat::MessageList
281
281
  #
282
282
  # @return [ String ] the location information
283
283
  def at_location
284
- if @chat.location.on?
285
- location_name = config.location.name
286
- location_decimal_degrees = config.location.decimal_degrees * ', '
287
- localtime = Time.now.iso8601
288
- units = config.location.units
289
- config.prompts.location % {
290
- location_name:, location_decimal_degrees:, localtime:, units:,
291
- }
292
- end.to_s
284
+ @chat.location_description if @chat.location.on?
293
285
  end
294
286
 
295
287
  # The use_pager method wraps the given block with a pager context.
@@ -87,7 +87,16 @@ vim:
87
87
  tools:
88
88
  get_current_weather:
89
89
  station_id: '00433'
90
+ default: false
90
91
  get_cve:
91
92
  url: 'https://cveawg.mitre.org/api/cve/%{cve_id}'
93
+ default: false
92
94
  get_endoflife:
93
95
  url: "https://endoflife.date/api/v1/products/%{product}"
96
+ default: false
97
+ get_location:
98
+ default: true
99
+ file_context:
100
+ default: false
101
+ directory_structure:
102
+ default: false
@@ -37,7 +37,10 @@ module OllamaChat::ToolCalling
37
37
  # This method outputs to standard output the alphabetically sorted list of
38
38
  # tool names that are currently enabled in the chat session.
39
39
  def list_tools
40
- puts @enabled_tools.sort
40
+ configured_tools.each do |tool|
41
+ enabled = @enabled_tools.member?(tool) ? ?✓ : ?☐
42
+ printf "%s %s\n", enabled, (enabled ? bold { tool } : tool)
43
+ end
41
44
  end
42
45
 
43
46
  # The enable_tool method allows the user to select and enable a tool from a
@@ -57,7 +60,7 @@ module OllamaChat::ToolCalling
57
60
  when *select_tools
58
61
  @enabled_tools << chosen
59
62
  @enabled_tools.sort!
60
- puts "Enabled tool %s" % bold(chosen)
63
+ puts "Enabled tool %s" % bold { chosen }
61
64
  end
62
65
  end
63
66
 
@@ -78,7 +81,7 @@ module OllamaChat::ToolCalling
78
81
  return
79
82
  when *select_tools
80
83
  @enabled_tools.delete chosen
81
- puts "Disabled tool %s" % bold(chosen)
84
+ puts "Disabled tool %s" % bold { chosen }
82
85
  end
83
86
  end
84
87
 
@@ -0,0 +1,120 @@
1
+ # A tool for retrieving directory structure and file hierarchy.
2
+ #
3
+ # This tool allows the chat client to retrieve the directory structure and file
4
+ # hierarchy for a given path. It integrates with the Ollama tool calling system
5
+ # to provide detailed directory information to the language model.
6
+ #
7
+ # The tool supports traversing directories up to a specified depth and returns
8
+ # a structured representation of the file system hierarchy.
9
+ class OllamaChat::Tools::DirectoryStructure
10
+ include Ollama
11
+
12
+ # Initializes a new directory_structure tool instance.
13
+ #
14
+ # @return [OllamaChat::Tools::DirectoryStructure] a new directory_structure tool instance
15
+ def initialize
16
+ @name = 'directory_structure'
17
+ end
18
+
19
+ # Returns the name of the tool.
20
+ #
21
+ # @return [String] the name of the tool ('directory_structure')
22
+ attr_reader :name
23
+
24
+ # Creates and returns a tool definition for retrieving directory structure.
25
+ #
26
+ # This method constructs the function signature that describes what the tool
27
+ # does, its parameters, and required fields. The tool accepts path and depth
28
+ # parameters for directory traversal.
29
+ #
30
+ # @return [Ollama::Tool] a tool definition for retrieving directory structure
31
+ def tool
32
+ Tool.new(
33
+ type: 'function',
34
+ function: Tool::Function.new(
35
+ name:,
36
+ description: 'Retrieve the directory structure and file hierarchy for a given path',
37
+ parameters: Tool::Function::Parameters.new(
38
+ type: 'object',
39
+ properties: {
40
+ path: Tool::Function::Parameters::Property.new(
41
+ type: 'string',
42
+ description: 'Path to directory to list (defaults to current directory)'
43
+ ),
44
+ depth: Tool::Function::Parameters::Property.new(
45
+ type: 'integer',
46
+ description: 'Depth of directory traversal (defaults to 2)'
47
+ )
48
+ },
49
+ required: []
50
+ )
51
+ )
52
+ )
53
+ end
54
+
55
+ # Executes the directory structure retrieval operation.
56
+ #
57
+ # This method traverses the directory structure starting from the specified
58
+ # path up to the given depth and returns a structured representation of
59
+ # the file system hierarchy.
60
+ #
61
+ # @param tool_call [Ollama::Tool::Call] the tool call object containing function details
62
+ # @param opts [Hash] additional options
63
+ # @return [String] the directory structure as a JSON string
64
+ # @raise [StandardError] if there's an issue with directory traversal or JSON serialization
65
+ def execute(tool_call, **opts)
66
+ path = Pathname.new(tool_call.function.arguments.path || '.')
67
+ depth = (tool_call.function.arguments.depth || 2).to_i
68
+
69
+ structure = generate_structure(path, depth)
70
+ structure.to_json
71
+ end
72
+
73
+ # Converts the tool to a hash representation.
74
+ #
75
+ # This method provides a standardized way to serialize the tool definition
76
+ # for use in tool calling systems.
77
+ #
78
+ # @return [Hash] a hash representation of the tool
79
+ def to_hash
80
+ tool.to_hash
81
+ end
82
+
83
+ private
84
+
85
+ # Generates the directory structure recursively.
86
+ #
87
+ # This method traverses the directory tree recursively up to the specified depth
88
+ # and builds a structured representation of files and directories.
89
+ #
90
+ # @param path [Pathname] the path to traverse
91
+ # @param depth [Integer] the maximum depth to traverse
92
+ # @param current_depth [Integer] the current traversal depth (used internally)
93
+ # @return [Array<Hash>, Hash] an array of directory and file entries, or an
94
+ # error hash if an exception occurs
95
+ def generate_structure(path, depth, current_depth = 0)
96
+ return [] if current_depth > depth
97
+
98
+ entries = []
99
+ path.children.sort.each do |child|
100
+ # Skip hidden files/directories
101
+ next if child.basename.to_s.start_with?('.')
102
+
103
+ if child.directory?
104
+ entries << {
105
+ type: 'directory',
106
+ name: child.basename.to_s,
107
+ children: generate_structure(child, depth, current_depth + 1)
108
+ }
109
+ else
110
+ entries << {
111
+ type: 'file',
112
+ name: child.basename.to_s
113
+ }
114
+ end
115
+ end
116
+ entries
117
+ rescue => e
118
+ { error: e.class, message: e.message }
119
+ end
120
+ end
@@ -0,0 +1,93 @@
1
+ # A tool for creating file context based on glob patterns.
2
+ #
3
+ # This tool allows the chat client to generate context information about files
4
+ # matching a specified glob pattern. It integrates with the Ollama tool calling
5
+ # system to provide detailed file information to the language model for more
6
+ # accurate responses.
7
+ #
8
+ # The tool searches for files using the provided glob pattern and generates
9
+ # structured context data that includes file contents, sizes, and metadata.
10
+ class OllamaChat::Tools::FileContext
11
+ include Ollama
12
+
13
+ # Initializes a new file_context tool instance.
14
+ #
15
+ # @return [OllamaChat::Tools::FileContext] a new file_context tool instance
16
+ def initialize
17
+ @name = 'file_context'
18
+ end
19
+
20
+ # Returns the name of the tool.
21
+ #
22
+ # @return [String] the name of the tool ('file_context')
23
+ attr_reader :name
24
+
25
+ # Creates and returns a tool definition for generating file context.
26
+ #
27
+ # This method constructs the function signature that describes what the tool
28
+ # does, its parameters, and required fields. The tool expects a pattern parameter
29
+ # to be provided for file searching.
30
+ #
31
+ # @return [Ollama::Tool] a tool definition for generating file context
32
+ def tool
33
+ Tool.new(
34
+ type: 'function',
35
+ function: Tool::Function.new(
36
+ name:,
37
+ description: 'Create a context that provides information about files '\
38
+ 'and their content in order to give more accurate answers for a query',
39
+ parameters: Tool::Function::Parameters.new(
40
+ type: 'object',
41
+ properties: {
42
+ pattern: Tool::Function::Parameters::Property.new(
43
+ type: 'string',
44
+ description: 'Glob pattern to search for (e.g., "**/*.rb", "lib/**/*.rb")'
45
+ ),
46
+ directory: Tool::Function::Parameters::Property.new(
47
+ type: 'string',
48
+ description: 'Directory to search in (defaults to current directory)'
49
+ ),
50
+ },
51
+ required: ['pattern']
52
+ )
53
+ )
54
+ )
55
+ end
56
+
57
+ # Executes the file context generation operation.
58
+ #
59
+ # This method searches for files matching the provided glob pattern and
60
+ # generates structured context data including file contents, sizes, and metadata.
61
+ #
62
+ # @param tool_call [Ollama::Tool::Call] the tool call object containing function details
63
+ # @param opts [Hash] additional options
64
+ # @option opts [ComplexConfig::Settings] :config the configuration object
65
+ # @return [String] the formatted context data as a string in the configured format
66
+ # @raise [StandardError] if there's an issue with file searching or context generation
67
+ def execute(tool_call, **opts)
68
+ config = opts[:config]
69
+ pattern = tool_call.function.arguments.pattern
70
+ directory = Pathname.new(tool_call.function.arguments.directory || ?.)
71
+ format = config.context.format
72
+ search_path = directory + pattern
73
+
74
+ ContextSpook::generate_context(verbose: true, format:) do |context|
75
+ context do
76
+ Dir.glob(search_path).each do |filename|
77
+ File.file?(filename) or next
78
+ file filename
79
+ end
80
+ end
81
+ end.send("to_#{format.downcase}")
82
+ end
83
+
84
+ # Converts the tool to a hash representation.
85
+ #
86
+ # This method provides a standardized way to serialize the tool definition
87
+ # for use in tool calling systems.
88
+ #
89
+ # @return [Hash] a hash representation of the tool
90
+ def to_hash
91
+ tool.to_hash
92
+ end
93
+ end
@@ -0,0 +1,69 @@
1
+ # A tool for retrieving the current location, time, and system of units.
2
+ #
3
+ # This tool allows the chat client to get the current location information,
4
+ # including time and system of units for the user. It integrates with the
5
+ # Ollama tool calling system to provide contextual location data to the language model.
6
+ #
7
+ # The tool returns structured JSON data containing location coordinates, time,
8
+ # and unit system information.
9
+ class OllamaChat::Tools::Location
10
+ include Ollama
11
+
12
+ # Initializes a new get_location tool instance.
13
+ #
14
+ # @return [OllamaChat::Tools::Location] a new get_location tool instance
15
+ def initialize
16
+ @name = 'get_location'
17
+ end
18
+
19
+ # Returns the name of the tool.
20
+ #
21
+ # @return [String] the name of the tool ('get_location')
22
+ attr_reader :name
23
+
24
+ # Creates and returns a tool definition for getting location information.
25
+ #
26
+ # This method constructs the function signature that describes what the tool
27
+ # does, its parameters, and required fields. The tool takes no parameters.
28
+ #
29
+ # @return [Ollama::Tool] a tool definition for retrieving location information
30
+ def tool
31
+ Tool.new(
32
+ type: 'function',
33
+ function: Tool::Function.new(
34
+ name:,
35
+ description: 'Get the current location, time and system of units of the user as JSON',
36
+ parameters: Tool::Function::Parameters.new(
37
+ type: 'object',
38
+ properties: {},
39
+ required: []
40
+ )
41
+ )
42
+ )
43
+ end
44
+
45
+ # Executes the location retrieval operation.
46
+ #
47
+ # This method fetches the current location data from the chat instance
48
+ # and returns it as JSON.
49
+ #
50
+ # @param tool_call [Ollama::Tool::Call] the tool call object containing function details
51
+ # @param opts [Hash] additional options
52
+ # @option opts [OllamaChat::Chat] :chat the chat instance containing location data
53
+ # @return [String] the location data as a JSON string
54
+ # @raise [StandardError] if there's an issue with location data retrieval or JSON serialization
55
+ def execute(tool_call, **opts)
56
+ chat = opts[:chat]
57
+ chat.location_data.to_json
58
+ end
59
+
60
+ # Converts the tool to a hash representation.
61
+ #
62
+ # This method provides a standardized way to serialize the tool definition
63
+ # for use in tool calling systems.
64
+ #
65
+ # @return [Hash] a hash representation of the tool
66
+ def to_hash
67
+ tool.to_hash
68
+ end
69
+ end
@@ -17,6 +17,7 @@ module OllamaChat::Tools
17
17
  #
18
18
  # @return [Class] the class itself
19
19
  def register(tool)
20
+ tool = tool.new if tool.is_a?(Class)
20
21
  registered[tool.name] = tool
21
22
  self
22
23
  end
@@ -25,8 +26,14 @@ module OllamaChat::Tools
25
26
  self.registered = {}
26
27
  end
27
28
  require 'ollama_chat/tools/weather'
28
- OllamaChat::Tools.register OllamaChat::Tools::Weather.new
29
+ OllamaChat::Tools.register OllamaChat::Tools::Weather
29
30
  require 'ollama_chat/tools/cve'
30
- OllamaChat::Tools.register OllamaChat::Tools::CVE.new
31
+ OllamaChat::Tools.register OllamaChat::Tools::CVE
31
32
  require 'ollama_chat/tools/endoflife'
32
- OllamaChat::Tools.register OllamaChat::Tools::EndOfLife.new
33
+ OllamaChat::Tools.register OllamaChat::Tools::EndOfLife
34
+ require 'ollama_chat/tools/location'
35
+ OllamaChat::Tools.register OllamaChat::Tools::Location
36
+ require 'ollama_chat/tools/file_context'
37
+ OllamaChat::Tools.register OllamaChat::Tools::FileContext
38
+ require 'ollama_chat/tools/directory_structure'
39
+ OllamaChat::Tools.register OllamaChat::Tools::DirectoryStructure
@@ -1,6 +1,6 @@
1
1
  module OllamaChat
2
2
  # OllamaChat version
3
- VERSION = '0.0.59'
3
+ VERSION = '0.0.60'
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
@@ -39,6 +39,7 @@ require 'ollama_chat/kramdown_ansi'
39
39
  require 'ollama_chat/conversation'
40
40
  require 'ollama_chat/input_content'
41
41
  require 'ollama_chat/message_editing'
42
+ require 'ollama_chat/location_handling'
42
43
  require 'ollama_chat/env_config'
43
44
  require 'ollama_chat/tools'
44
45
  require 'ollama_chat/tool_calling'
data/ollama_chat.gemspec CHANGED
@@ -1,9 +1,9 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: ollama_chat 0.0.59 ruby lib
2
+ # stub: ollama_chat 0.0.60 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "ollama_chat".freeze
6
- s.version = "0.0.59".freeze
6
+ s.version = "0.0.60".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/state_selectors.rb".freeze, "lib/ollama_chat/switches.rb".freeze, "lib/ollama_chat/think_control.rb".freeze, "lib/ollama_chat/tool_calling.rb".freeze, "lib/ollama_chat/tools.rb".freeze, "lib/ollama_chat/tools/cve.rb".freeze, "lib/ollama_chat/tools/endoflife.rb".freeze, "lib/ollama_chat/tools/weather.rb".freeze, "lib/ollama_chat/tools/weather/dwd_sensor.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/tool_calling.rb".freeze, "lib/ollama_chat/tools.rb".freeze, "lib/ollama_chat/tools/cve.rb".freeze, "lib/ollama_chat/tools/endoflife.rb".freeze, "lib/ollama_chat/tools/weather.rb".freeze, "lib/ollama_chat/tools/weather/dwd_sensor.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/tools/cve_spec.rb".freeze, "spec/ollama_chat/tools/endoflife_spec.rb".freeze, "spec/ollama_chat/tools/weather_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/location_handling.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/tool_calling.rb".freeze, "lib/ollama_chat/tools.rb".freeze, "lib/ollama_chat/tools/cve.rb".freeze, "lib/ollama_chat/tools/directory_structure.rb".freeze, "lib/ollama_chat/tools/endoflife.rb".freeze, "lib/ollama_chat/tools/file_context.rb".freeze, "lib/ollama_chat/tools/location.rb".freeze, "lib/ollama_chat/tools/weather.rb".freeze, "lib/ollama_chat/tools/weather/dwd_sensor.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/location_handling.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/tool_calling.rb".freeze, "lib/ollama_chat/tools.rb".freeze, "lib/ollama_chat/tools/cve.rb".freeze, "lib/ollama_chat/tools/directory_structure.rb".freeze, "lib/ollama_chat/tools/endoflife.rb".freeze, "lib/ollama_chat/tools/file_context.rb".freeze, "lib/ollama_chat/tools/location.rb".freeze, "lib/ollama_chat/tools/weather.rb".freeze, "lib/ollama_chat/tools/weather/dwd_sensor.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/deep/deeper/empty.txt".freeze, "spec/assets/deep/deeper/not-empty.txt".freeze, "spec/assets/deep/empty.txt".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/tools/cve_spec.rb".freeze, "spec/ollama_chat/tools/directory_structure_spec.rb".freeze, "spec/ollama_chat/tools/endoflife_spec.rb".freeze, "spec/ollama_chat/tools/file_content_spec.rb".freeze, "spec/ollama_chat/tools/location_spec.rb".freeze, "spec/ollama_chat/tools/weather_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/state_selectors_spec.rb".freeze, "spec/ollama_chat/switches_spec.rb".freeze, "spec/ollama_chat/think_control_spec.rb".freeze, "spec/ollama_chat/tools/cve_spec.rb".freeze, "spec/ollama_chat/tools/endoflife_spec.rb".freeze, "spec/ollama_chat/tools/weather_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/tools/cve_spec.rb".freeze, "spec/ollama_chat/tools/directory_structure_spec.rb".freeze, "spec/ollama_chat/tools/endoflife_spec.rb".freeze, "spec/ollama_chat/tools/file_content_spec.rb".freeze, "spec/ollama_chat/tools/location_spec.rb".freeze, "spec/ollama_chat/tools/weather_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
 
File without changes
@@ -0,0 +1 @@
1
+ not-empty
File without changes
@@ -43,14 +43,14 @@ describe OllamaChat::InputContent do
43
43
  describe '#choose_filename' do
44
44
  it 'can select a file from matching patterns' do
45
45
  # Test with a pattern that matches existing files
46
- files = Dir.glob('spec/assets/*')
46
+ files = Dir.glob('spec/assets/**/*.txt')
47
47
  expect(files).to_not be_empty
48
48
 
49
49
  # Mock the selection process
50
50
  expect(OllamaChat::Utils::Chooser).to receive(:choose).
51
51
  with(files.unshift('[EXIT]')).and_return(files[1])
52
52
 
53
- result = chat.choose_filename('spec/assets/*')
53
+ result = chat.choose_filename('spec/assets/**/*.txt')
54
54
  expect(result).to eq files[1]
55
55
  end
56
56
 
@@ -23,6 +23,10 @@ describe OllamaChat::MessageList do
23
23
  double('Chat', config:)
24
24
  end
25
25
 
26
+ before do
27
+ chat.extend OllamaChat::LocationHandling
28
+ end
29
+
26
30
  before do
27
31
  allow(chat).to receive(:kramdown_ansi_parse) do |content|
28
32
  Kramdown::ANSI.parse(content)
@@ -0,0 +1,82 @@
1
+ require 'spec_helper'
2
+
3
+ describe OllamaChat::Tools::DirectoryStructure do
4
+ let(:chat) do
5
+ OllamaChat::Chat.new(argv: chat_default_config)
6
+ end
7
+
8
+ connect_to_ollama_server
9
+
10
+ it 'can have name' do
11
+ expect(described_class.new.name).to eq 'directory_structure'
12
+ end
13
+
14
+ it 'can have tool' do
15
+ expect(described_class.new.tool).to be_a Ollama::Tool
16
+ end
17
+
18
+ it 'can be executed successfully with path and depth' do
19
+ tool_call = double(
20
+ 'ToolCall',
21
+ function: double(
22
+ name: 'directory_structure',
23
+ arguments: double(
24
+ path: 'spec/assets',
25
+ depth: 3
26
+ )
27
+ )
28
+ )
29
+
30
+ result = described_class.new.execute(tool_call)
31
+
32
+ # Should return valid JSON
33
+ expect(result).to be_a(String)
34
+ json = JSON.parse(result, object_class: JSON::GenericObject)
35
+ expect(json.size).to eq 18
36
+ end
37
+
38
+ it 'can be executed successfully with no arguments (defaults)' do
39
+ tool_call = double(
40
+ 'ToolCall',
41
+ function: double(
42
+ name: 'directory_structure',
43
+ arguments: double(
44
+ path: nil, # Should default to '.'
45
+ depth: nil # Should default to 2
46
+ )
47
+ )
48
+ )
49
+
50
+ result = described_class.new.execute(tool_call)
51
+
52
+ # Should return valid JSON
53
+ expect(result).to be_a(String)
54
+ json = JSON.parse(result, object_class: JSON::GenericObject)
55
+ expect(json.size).to be > 18
56
+ end
57
+
58
+ it 'can handle execution errors gracefully' do
59
+ tool_call = double(
60
+ 'ToolCall',
61
+ function: double(
62
+ name: 'directory_structure',
63
+ arguments: double(
64
+ path: '/nonexistent/path',
65
+ depth: 2
66
+ )
67
+ )
68
+ )
69
+
70
+ # Test that it handles non-existent paths gracefully
71
+ result = described_class.new.execute(tool_call)
72
+
73
+ # Should return valid JSON
74
+ expect(result).to be_a(String)
75
+ json = JSON.parse(result, object_class: JSON::GenericObject)
76
+ expect(json.error).to eq 'Errno::ENOENT'
77
+ end
78
+
79
+ it 'can be converted to hash' do
80
+ expect(described_class.new.to_hash).to be_a Hash
81
+ end
82
+ end
@@ -0,0 +1,63 @@
1
+ require 'spec_helper'
2
+
3
+ describe OllamaChat::Tools::FileContext do
4
+ let :chat do
5
+ OllamaChat::Chat.new(argv: chat_default_config)
6
+ end
7
+
8
+ let :config do
9
+ double('Config', context: double(format: 'JSON'))
10
+ end
11
+
12
+ connect_to_ollama_server
13
+
14
+ it 'can have name' do
15
+ expect(described_class.new.name).to eq 'file_context'
16
+ end
17
+
18
+ it 'can have tool' do
19
+ expect(described_class.new.tool).to be_a Ollama::Tool
20
+ end
21
+
22
+ it 'can be executed successfully with pattern and directory' do
23
+ tool_call = double(
24
+ 'ToolCall',
25
+ function: double(
26
+ name: 'file_context',
27
+ arguments: double(
28
+ pattern: '**/*.rb',
29
+ directory: 'spec/assets'
30
+ )
31
+ )
32
+ )
33
+
34
+ # Test with actual files in spec/assets
35
+ result = described_class.new.execute(tool_call, config: config)
36
+ expect(result).to be_a(String)
37
+ json = JSON.parse(result, object_class: JSON::GenericObject)
38
+ expect(json.files['spec/assets/example.rb'].content).to include 'Hello World!'
39
+ end
40
+
41
+ it 'can handle execution errors gracefully' do
42
+ tool_call = double(
43
+ 'ToolCall',
44
+ function: double(
45
+ name: 'file_context',
46
+ arguments: double(
47
+ pattern: '**/*.nonexistent',
48
+ directory: 'spec/assets'
49
+ )
50
+ )
51
+ )
52
+
53
+ # Test that it handles non-existent patterns gracefully
54
+ result = described_class.new.execute(tool_call, config: config)
55
+
56
+ # Should still return a string (even if empty or minimal)
57
+ expect(result).to be_a(String)
58
+ end
59
+
60
+ it 'can be converted to hash' do
61
+ expect(described_class.new.to_hash).to be_a Hash
62
+ end
63
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe OllamaChat::Tools::Location do
4
+ let(:chat) do
5
+ OllamaChat::Chat.new(argv: chat_default_config)
6
+ end
7
+
8
+ connect_to_ollama_server
9
+
10
+ it 'can have name' do
11
+ expect(described_class.new.name).to eq 'get_location'
12
+ end
13
+
14
+ it 'can have tool' do
15
+ expect(described_class.new.tool).to be_a Ollama::Tool
16
+ end
17
+
18
+ it 'can be executed successfully' do
19
+ # Mock the chat instance with location_data
20
+ location_data = {
21
+ latitude: 40.7128,
22
+ longitude: -74.0060,
23
+ time: '2023-05-15T14:30:00Z',
24
+ units: 'metric'
25
+ }
26
+
27
+ chat_instance = double('Chat', location_data: location_data)
28
+
29
+ tool_call = double(
30
+ 'ToolCall',
31
+ function: double(
32
+ name: 'get_location',
33
+ arguments: double()
34
+ )
35
+ )
36
+
37
+ result = described_class.new.execute(tool_call, chat: chat_instance)
38
+
39
+ # Parse the JSON result to verify content
40
+ parsed_result = JSON.parse(result)
41
+ expect(parsed_result['latitude']).to be_within(0.0001).of(40.7128)
42
+ expect(parsed_result['longitude']).to be_within(0.0001).of(-74.0060)
43
+ expect(parsed_result['time']).to eq '2023-05-15T14:30:00Z'
44
+ expect(parsed_result['units']).to eq 'metric'
45
+ end
46
+
47
+ it 'can handle execution errors gracefully' do
48
+ # Mock a chat instance that raises an error when accessing location_data
49
+ chat_instance = double('Chat', location_data: nil)
50
+
51
+ tool_call = double(
52
+ 'ToolCall',
53
+ function: double(
54
+ name: 'get_location',
55
+ arguments: double()
56
+ )
57
+ )
58
+
59
+ # Test that the method handles nil location_data gracefully
60
+ expect {
61
+ described_class.new.execute(tool_call, chat: chat_instance)
62
+ }.to_not raise_error
63
+ end
64
+
65
+ it 'can be converted to hash' do
66
+ expect(described_class.new.to_hash).to be_a Hash
67
+ end
68
+
69
+ context 'when location_data is not available' do
70
+ it 'returns valid JSON even with missing data' do
71
+ chat_instance = double('Chat', location_data: nil)
72
+
73
+ tool_call = double(
74
+ 'ToolCall',
75
+ function: double(
76
+ name: 'get_location',
77
+ arguments: double()
78
+ )
79
+ )
80
+
81
+ result = described_class.new.execute(tool_call, chat: chat_instance)
82
+ # Should still be valid JSON even if location_data is nil
83
+ expect { JSON.parse(result) }.to_not raise_error
84
+ end
85
+ end
86
+ end
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.59
4
+ version: 0.0.60
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Frank
@@ -448,6 +448,7 @@ extra_rdoc_files:
448
448
  - lib/ollama_chat/information.rb
449
449
  - lib/ollama_chat/input_content.rb
450
450
  - lib/ollama_chat/kramdown_ansi.rb
451
+ - lib/ollama_chat/location_handling.rb
451
452
  - lib/ollama_chat/message_editing.rb
452
453
  - lib/ollama_chat/message_format.rb
453
454
  - lib/ollama_chat/message_list.rb
@@ -464,7 +465,10 @@ extra_rdoc_files:
464
465
  - lib/ollama_chat/tool_calling.rb
465
466
  - lib/ollama_chat/tools.rb
466
467
  - lib/ollama_chat/tools/cve.rb
468
+ - lib/ollama_chat/tools/directory_structure.rb
467
469
  - lib/ollama_chat/tools/endoflife.rb
470
+ - lib/ollama_chat/tools/file_context.rb
471
+ - lib/ollama_chat/tools/location.rb
468
472
  - lib/ollama_chat/tools/weather.rb
469
473
  - lib/ollama_chat/tools/weather/dwd_sensor.rb
470
474
  - lib/ollama_chat/utils.rb
@@ -497,6 +501,7 @@ files:
497
501
  - lib/ollama_chat/information.rb
498
502
  - lib/ollama_chat/input_content.rb
499
503
  - lib/ollama_chat/kramdown_ansi.rb
504
+ - lib/ollama_chat/location_handling.rb
500
505
  - lib/ollama_chat/message_editing.rb
501
506
  - lib/ollama_chat/message_format.rb
502
507
  - lib/ollama_chat/message_list.rb
@@ -514,7 +519,10 @@ files:
514
519
  - lib/ollama_chat/tool_calling.rb
515
520
  - lib/ollama_chat/tools.rb
516
521
  - lib/ollama_chat/tools/cve.rb
522
+ - lib/ollama_chat/tools/directory_structure.rb
517
523
  - lib/ollama_chat/tools/endoflife.rb
524
+ - lib/ollama_chat/tools/file_context.rb
525
+ - lib/ollama_chat/tools/location.rb
518
526
  - lib/ollama_chat/tools/weather.rb
519
527
  - lib/ollama_chat/tools/weather/dwd_sensor.rb
520
528
  - lib/ollama_chat/utils.rb
@@ -531,6 +539,9 @@ files:
531
539
  - spec/assets/api_tags.json
532
540
  - spec/assets/api_version.json
533
541
  - spec/assets/conversation.json
542
+ - spec/assets/deep/deeper/empty.txt
543
+ - spec/assets/deep/deeper/not-empty.txt
544
+ - spec/assets/deep/empty.txt
534
545
  - spec/assets/duckduckgo.html
535
546
  - spec/assets/example.atom
536
547
  - spec/assets/example.csv
@@ -562,7 +573,10 @@ files:
562
573
  - spec/ollama_chat/switches_spec.rb
563
574
  - spec/ollama_chat/think_control_spec.rb
564
575
  - spec/ollama_chat/tools/cve_spec.rb
576
+ - spec/ollama_chat/tools/directory_structure_spec.rb
565
577
  - spec/ollama_chat/tools/endoflife_spec.rb
578
+ - spec/ollama_chat/tools/file_content_spec.rb
579
+ - spec/ollama_chat/tools/location_spec.rb
566
580
  - spec/ollama_chat/tools/weather_spec.rb
567
581
  - spec/ollama_chat/utils/cache_fetcher_spec.rb
568
582
  - spec/ollama_chat/utils/fetcher_spec.rb
@@ -616,7 +630,10 @@ test_files:
616
630
  - spec/ollama_chat/switches_spec.rb
617
631
  - spec/ollama_chat/think_control_spec.rb
618
632
  - spec/ollama_chat/tools/cve_spec.rb
633
+ - spec/ollama_chat/tools/directory_structure_spec.rb
619
634
  - spec/ollama_chat/tools/endoflife_spec.rb
635
+ - spec/ollama_chat/tools/file_content_spec.rb
636
+ - spec/ollama_chat/tools/location_spec.rb
620
637
  - spec/ollama_chat/tools/weather_spec.rb
621
638
  - spec/ollama_chat/utils/cache_fetcher_spec.rb
622
639
  - spec/ollama_chat/utils/fetcher_spec.rb