aia 0.9.1 → 0.9.3rc1

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.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aia
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.9.3rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dewayne VanHoozer
@@ -37,50 +37,36 @@ dependencies:
37
37
  - - ">="
38
38
  - !ruby/object:Gem::Version
39
39
  version: '0'
40
- - !ruby/object:Gem::Dependency
41
- name: os
42
- requirement: !ruby/object:Gem::Requirement
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: '0'
47
- type: :runtime
48
- prerelease: false
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: '0'
54
40
  - !ruby/object:Gem::Dependency
55
41
  name: prompt_manager
56
42
  requirement: !ruby/object:Gem::Requirement
57
43
  requirements:
58
44
  - - ">="
59
45
  - !ruby/object:Gem::Version
60
- version: 0.5.2
46
+ version: 0.5.4
61
47
  type: :runtime
62
48
  prerelease: false
63
49
  version_requirements: !ruby/object:Gem::Requirement
64
50
  requirements:
65
51
  - - ">="
66
52
  - !ruby/object:Gem::Version
67
- version: 0.5.2
53
+ version: 0.5.4
68
54
  - !ruby/object:Gem::Dependency
69
55
  name: ruby_llm
70
56
  requirement: !ruby/object:Gem::Requirement
71
57
  requirements:
72
58
  - - ">="
73
59
  - !ruby/object:Gem::Version
74
- version: 1.2.0
60
+ version: 1.3.0rc1
75
61
  type: :runtime
76
62
  prerelease: false
77
63
  version_requirements: !ruby/object:Gem::Requirement
78
64
  requirements:
79
65
  - - ">="
80
66
  - !ruby/object:Gem::Version
81
- version: 1.2.0
67
+ version: 1.3.0rc1
82
68
  - !ruby/object:Gem::Dependency
83
- name: ruby-mcp-client
69
+ name: reline
84
70
  requirement: !ruby/object:Gem::Requirement
85
71
  requirements:
86
72
  - - ">="
@@ -94,7 +80,7 @@ dependencies:
94
80
  - !ruby/object:Gem::Version
95
81
  version: '0'
96
82
  - !ruby/object:Gem::Dependency
97
- name: reline
83
+ name: shellwords
98
84
  requirement: !ruby/object:Gem::Requirement
99
85
  requirements:
100
86
  - - ">="
@@ -108,7 +94,7 @@ dependencies:
108
94
  - !ruby/object:Gem::Version
109
95
  version: '0'
110
96
  - !ruby/object:Gem::Dependency
111
- name: shellwords
97
+ name: toml-rb
112
98
  requirement: !ruby/object:Gem::Requirement
113
99
  requirements:
114
100
  - - ">="
@@ -122,7 +108,7 @@ dependencies:
122
108
  - !ruby/object:Gem::Version
123
109
  version: '0'
124
110
  - !ruby/object:Gem::Dependency
125
- name: toml-rb
111
+ name: tty-screen
126
112
  requirement: !ruby/object:Gem::Requirement
127
113
  requirements:
128
114
  - - ">="
@@ -136,7 +122,7 @@ dependencies:
136
122
  - !ruby/object:Gem::Version
137
123
  version: '0'
138
124
  - !ruby/object:Gem::Dependency
139
- name: tty-screen
125
+ name: tty-spinner
140
126
  requirement: !ruby/object:Gem::Requirement
141
127
  requirements:
142
128
  - - ">="
@@ -150,7 +136,7 @@ dependencies:
150
136
  - !ruby/object:Gem::Version
151
137
  version: '0'
152
138
  - !ruby/object:Gem::Dependency
153
- name: tty-spinner
139
+ name: versionaire
154
140
  requirement: !ruby/object:Gem::Requirement
155
141
  requirements:
156
142
  - - ">="
@@ -164,7 +150,7 @@ dependencies:
164
150
  - !ruby/object:Gem::Version
165
151
  version: '0'
166
152
  - !ruby/object:Gem::Dependency
167
- name: versionaire
153
+ name: word_wrapper
168
154
  requirement: !ruby/object:Gem::Requirement
169
155
  requirements:
170
156
  - - ">="
@@ -302,6 +288,10 @@ files:
302
288
  - bin/aia
303
289
  - examples/README.md
304
290
  - examples/headlines
291
+ - examples/tools/edit_file.rb
292
+ - examples/tools/list_files.rb
293
+ - examples/tools/read_file.rb
294
+ - examples/tools/run_shell_command.rb
305
295
  - justfile
306
296
  - lib/aia.rb
307
297
  - lib/aia/aia_completion.bash
@@ -321,7 +311,6 @@ files:
321
311
  - lib/aia/utility.rb
322
312
  - lib/aia/version.rb
323
313
  - lib/extensions/openstruct_merge.rb
324
- - lib/extensions/ruby_llm/chat.rb
325
314
  - main.just
326
315
  - mcp_servers/README.md
327
316
  - mcp_servers/filesystem.json
@@ -1,197 +0,0 @@
1
- # lib/extensions/ruby_llm/chat.rb
2
-
3
- module RubyLLM
4
- class Chat
5
- class << self
6
- # Sets up Model Control Protocol (MCP) tools
7
- #
8
- # @param client [instance object] MCP client instance to use
9
- # @param call_tool_method [Symbol] Method name to use for tool execution
10
- # @param tools [Array<Hash>] Array of MCP tool definitions
11
- #
12
- # @return [self] Returns self for method chaining
13
- #
14
- def with_mcp(client:, call_tool_method:, tools:)
15
- # Validate all required parameters are present
16
- if client.nil?
17
- RubyLLM.logger.error "MCP setup failed: client must be provided"
18
- return clear_mcp_state
19
- end
20
-
21
- if call_tool_method.nil?
22
- RubyLLM.logger.error "MCP setup failed: call_tool_method must be provided"
23
- return clear_mcp_state
24
- end
25
-
26
- if tools.nil?
27
- RubyLLM.logger.error "MCP setup failed: tools must be provided"
28
- return clear_mcp_state
29
- end
30
-
31
- # Validate call_tool_method type
32
- unless call_tool_method.is_a?(Symbol) || call_tool_method.is_a?(String)
33
- RubyLLM.logger.error "MCP setup failed: call_tool_method must be a Symbol or String, got #{call_tool_method.class}"
34
- return clear_mcp_state
35
- end
36
-
37
- # Validate client responds to the method
38
- unless client.respond_to?(call_tool_method)
39
- RubyLLM.logger.error "MCP setup failed: client instance does not respond to call_tool_method #{call_tool_method}"
40
- return clear_mcp_state
41
- end
42
-
43
- # Set MCP configuration
44
- @mcp_client = client
45
- @mcp_call_tool = call_tool_method.to_sym
46
- @mcp_tools = tools
47
-
48
- self
49
- end
50
-
51
- # Get the MCP client instance if configured
52
- # @return [MCPClient::Client, nil] The MCP client instance or nil if not configured
53
- def mcp_client
54
- @mcp_client
55
- end
56
-
57
- # Get the method name to use for tool execution if configured
58
- # @return [Symbol, nil] The method name or nil if not configured
59
- def mcp_call_tool
60
- @mcp_call_tool
61
- end
62
-
63
- # Get the MCP tool definitions if configured
64
- # @return [Array<Hash>] The MCP tool definitions or empty array if not configured
65
- def mcp_tools
66
- @mcp_tools || []
67
- end
68
-
69
- private
70
-
71
- # Clear all MCP state and return self
72
- # @return [self]
73
- def clear_mcp_state
74
- @mcp_client = nil
75
- @mcp_call_tool = nil
76
- @mcp_tools = []
77
- self
78
- end
79
- end
80
-
81
- # Prepend a module to add MCP tool support
82
- module MCPSupport
83
- def initialize(...)
84
- super
85
- add_mcp_tools
86
- end
87
-
88
- private
89
-
90
- def add_mcp_tools
91
- self.class.mcp_tools.each do |tool_def|
92
- debug_me{[ :tool_def ]}
93
- tool_name = tool_def.dig(:function, :name).to_sym
94
- next if @tools.key?(tool_name) # Skip if local or MCP tool exists with same name
95
-
96
- @tools[tool_name] = MCPToolWrapper.new(tool_def)
97
- end
98
- end
99
- end
100
-
101
- # Add MCP support to the Chat class
102
- prepend MCPSupport
103
- end
104
-
105
- # Wraps an MCP tool definition to match the RubyLLM::Tool interface
106
- class MCPToolWrapper
107
- def initialize(mcp_tool)
108
- @mcp_tool = mcp_tool
109
- end
110
-
111
- def name
112
- @mcp_tool.dig(:function, :name)
113
- end
114
-
115
- def description
116
- @mcp_tool.dig(:function, :description)
117
- end
118
-
119
- # Simple parameter class that implements the interface expected by RubyLLM::Providers::OpenAI::Tools#param_schema
120
- class Parameter
121
- attr_reader :type, :description, :required
122
-
123
- def initialize(type, description, required)
124
- @type = type || 'string'
125
- @description = description
126
- @required = required
127
- end
128
- end
129
-
130
- def parameters
131
- @parameters ||= begin
132
- props = @mcp_tool.dig(:function, :parameters, "properties") || {}
133
- required_params = @mcp_tool.dig(:function, :parameters, "required") || []
134
-
135
- # Create Parameter objects with the expected interface
136
- # The parameter name is the key in the properties hash
137
- result = {}
138
- props.each do |param_name, param_def|
139
- result[param_name.to_sym] = Parameter.new(
140
- param_def["type"],
141
- param_def["description"],
142
- required_params.include?(param_name)
143
- )
144
- end
145
- result
146
- end
147
- end
148
-
149
- def call(args)
150
- # Log the tool call with arguments
151
- RubyLLM.logger.debug "Tool #{name} called with: #{args.inspect}"
152
-
153
- # Verify MCP client is configured properly
154
- unless Chat.mcp_client && Chat.mcp_call_tool
155
- error = { error: "MCP client not properly configured" }
156
- RubyLLM.logger.error error[:error]
157
- return error
158
- end
159
-
160
- # Handle tool calls that require non-string parameters
161
- normalized_args = {}
162
- args.each do |key, value|
163
- # Convert string numbers to actual numbers when needed
164
- if value.is_a?(String) && value.match?(/\A-?\d+(\.\d+)?\z/)
165
- param_type = @mcp_tool.dig(:function, :parameters, "properties", key.to_s, "type")
166
- if param_type == "number" || param_type == "integer"
167
- normalized_args[key] = value.include?('.') ? value.to_f : value.to_i
168
- next
169
- end
170
- end
171
- normalized_args[key] = value
172
- end
173
-
174
- # Execute the tool via the MCP client with a timeout
175
- timeout = 10 # seconds
176
- result = nil
177
-
178
- begin
179
- Timeout.timeout(timeout) do
180
- result = Chat.mcp_client.send(Chat.mcp_call_tool, name, normalized_args)
181
- end
182
- rescue Timeout::Error
183
- error = { error: "MCP tool execution timed out after #{timeout} seconds" }
184
- RubyLLM.logger.error error[:error]
185
- return error
186
- rescue StandardError => e
187
- error = { error: "MCP tool execution failed: #{e.message}" }
188
- RubyLLM.logger.error error[:error]
189
- return error
190
- end
191
-
192
- # Log the result
193
- RubyLLM.logger.debug "Tool #{name} returned: #{result.inspect}"
194
- result
195
- end
196
- end
197
- end