solid_agent 0.0.0 → 0.1.1

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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +130 -0
  3. data/Rakefile +12 -0
  4. data/lib/generators/solid_agent/agent/agent_generator.rb +95 -0
  5. data/lib/generators/solid_agent/agent/templates/action.text.erb +10 -0
  6. data/lib/generators/solid_agent/agent/templates/agent.rb.erb +93 -0
  7. data/lib/generators/solid_agent/context/context_generator.rb +124 -0
  8. data/lib/generators/solid_agent/context/templates/context_model.rb.erb +100 -0
  9. data/lib/generators/solid_agent/context/templates/create_context.rb.erb +32 -0
  10. data/lib/generators/solid_agent/context/templates/create_generations.rb.erb +38 -0
  11. data/lib/generators/solid_agent/context/templates/create_messages.rb.erb +33 -0
  12. data/lib/generators/solid_agent/context/templates/generation_model.rb.erb +40 -0
  13. data/lib/generators/solid_agent/context/templates/message_model.rb.erb +47 -0
  14. data/lib/generators/solid_agent/install/install_generator.rb +83 -0
  15. data/lib/generators/solid_agent/install/templates/agent_context.rb.erb +128 -0
  16. data/lib/generators/solid_agent/install/templates/agent_generation.rb.erb +59 -0
  17. data/lib/generators/solid_agent/install/templates/agent_message.rb.erb +76 -0
  18. data/lib/generators/solid_agent/install/templates/create_agent_contexts.rb.erb +32 -0
  19. data/lib/generators/solid_agent/install/templates/create_agent_generations.rb.erb +38 -0
  20. data/lib/generators/solid_agent/install/templates/create_agent_messages.rb.erb +33 -0
  21. data/lib/generators/solid_agent/install/templates/initializer.rb.erb +51 -0
  22. data/lib/generators/solid_agent/tool/templates/tool.json.erb +19 -0
  23. data/lib/generators/solid_agent/tool/tool_generator.rb +117 -0
  24. data/lib/solid_agent/engine.rb +16 -0
  25. data/lib/solid_agent/has_context.rb +449 -0
  26. data/lib/solid_agent/has_tools.rb +257 -0
  27. data/lib/solid_agent/streams_tool_updates.rb +178 -0
  28. data/lib/solid_agent/version.rb +5 -0
  29. data/lib/solid_agent.rb +28 -0
  30. data/sig/solid_agent.rbs +4 -0
  31. metadata +88 -14
@@ -0,0 +1,257 @@
1
+ # frozen_string_literal: true
2
+
3
+ # HasTools provides a DSL for defining and loading tool schemas in ActiveAgent agents.
4
+ #
5
+ # This concern enables declarative tool registration with automatic schema loading
6
+ # from JSON view templates or inline definitions.
7
+ #
8
+ # @example Auto-discover tools from views
9
+ # class MyAgent < ApplicationAgent
10
+ # include SolidAgent::HasTools
11
+ # has_tools # Discovers all tools from app/views/my_agent/tools/*.json.erb
12
+ # end
13
+ #
14
+ # @example Explicit tool list
15
+ # class MyAgent < ApplicationAgent
16
+ # include SolidAgent::HasTools
17
+ # has_tools :search, :fetch, :analyze
18
+ # end
19
+ #
20
+ # @example Inline tool definition
21
+ # class MyAgent < ApplicationAgent
22
+ # include SolidAgent::HasTools
23
+ # tool :get_weather do
24
+ # description "Get current weather for a location"
25
+ # parameter :location, type: :string, required: true, description: "City name"
26
+ # parameter :units, type: :string, enum: %w[celsius fahrenheit], default: "celsius"
27
+ # end
28
+ # end
29
+ #
30
+ # @example Mixed approach
31
+ # class MyAgent < ApplicationAgent
32
+ # include SolidAgent::HasTools
33
+ # has_tools :navigate, :click # Load from templates
34
+ # tool :custom_action do # Define inline
35
+ # description "A custom action"
36
+ # parameter :input, type: :string, required: true
37
+ # end
38
+ # end
39
+ module SolidAgent
40
+ module HasTools
41
+ extend ActiveSupport::Concern
42
+
43
+ included do
44
+ class_attribute :_tool_names, default: []
45
+ class_attribute :_inline_tools, default: {}
46
+ class_attribute :_tools_auto_discover, default: false
47
+ end
48
+
49
+ class_methods do
50
+ # Declares which tools this agent uses.
51
+ #
52
+ # Without arguments, enables auto-discovery of tools from view templates.
53
+ # With arguments, explicitly lists tools to load from templates.
54
+ #
55
+ # @param tool_names [Array<Symbol, String>] explicit list of tools to load
56
+ # @return [void]
57
+ #
58
+ # @example Auto-discover
59
+ # has_tools
60
+ #
61
+ # @example Explicit list
62
+ # has_tools :navigate, :click, :fill_form
63
+ def has_tools(*tool_names)
64
+ if tool_names.empty?
65
+ self._tools_auto_discover = true
66
+ else
67
+ self._tool_names = tool_names.map(&:to_sym)
68
+ end
69
+ end
70
+
71
+ # Defines a tool inline using a DSL block.
72
+ #
73
+ # The tool name should match a method in the agent class that will be
74
+ # called when the LLM invokes this tool.
75
+ #
76
+ # @param name [Symbol, String] tool name (must match an instance method)
77
+ # @yield block for defining tool schema using ToolBuilder DSL
78
+ # @return [void]
79
+ #
80
+ # @example
81
+ # tool :search do
82
+ # description "Search for documents"
83
+ # parameter :query, type: :string, required: true
84
+ # parameter :limit, type: :integer, default: 10
85
+ # end
86
+ def tool(name, &block)
87
+ builder = ToolBuilder.new(name)
88
+ builder.instance_eval(&block) if block_given?
89
+ self._inline_tools = _inline_tools.merge(name.to_sym => builder.to_schema)
90
+ end
91
+ end
92
+
93
+ # Returns all tool schemas for this agent.
94
+ #
95
+ # Combines tools from:
96
+ # 1. Auto-discovered JSON templates (if has_tools called without args)
97
+ # 2. Explicitly listed tools (if has_tools called with args)
98
+ # 3. Inline tool definitions (from tool blocks)
99
+ #
100
+ # @return [Array<Hash>] array of tool schemas in OpenAI format
101
+ def tools
102
+ @_tools_cache ||= begin
103
+ schemas = []
104
+
105
+ # Load from templates
106
+ if _tools_auto_discover
107
+ schemas.concat(discover_tool_templates)
108
+ elsif _tool_names.any?
109
+ schemas.concat(_tool_names.map { |name| load_tool_schema(name) })
110
+ end
111
+
112
+ # Add inline tools
113
+ schemas.concat(_inline_tools.values)
114
+
115
+ schemas
116
+ end
117
+ end
118
+
119
+ # Reloads tools, clearing any cached schemas.
120
+ #
121
+ # Useful when tool templates may have changed during development.
122
+ #
123
+ # @return [Array<Hash>] freshly loaded tool schemas
124
+ def reload_tools!
125
+ @_tools_cache = nil
126
+ tools
127
+ end
128
+
129
+ private
130
+
131
+ # Discovers tool templates from the agent's views directory.
132
+ #
133
+ # Looks for JSON templates in:
134
+ # - app/views/{agent_name}/tools/*.json.erb
135
+ # - app/views/agents/{agent_without_suffix}/tools/*.json.erb
136
+ #
137
+ # @return [Array<Hash>] discovered tool schemas
138
+ def discover_tool_templates
139
+ tool_schemas = []
140
+ tools_path = Rails.root.join("app", "views", agent_name, "tools")
141
+
142
+ if tools_path.exist?
143
+ tools_path.glob("*.json.erb").each do |template_path|
144
+ tool_name = template_path.basename(".json.erb").to_s
145
+ tool_schemas << load_tool_schema(tool_name)
146
+ end
147
+ end
148
+
149
+ # Also check nested structure: app/views/agents/{name}/tools/
150
+ nested_path = Rails.root.join("app", "views", "agents", agent_name.delete_suffix("_agent"), "tools")
151
+ if nested_path.exist?
152
+ nested_path.glob("*.json.erb").each do |template_path|
153
+ tool_name = template_path.basename(".json.erb").to_s
154
+ # Avoid duplicates
155
+ next if tool_schemas.any? { |t| t[:name] == tool_name }
156
+ tool_schemas << load_tool_schema(tool_name)
157
+ end
158
+ end
159
+
160
+ tool_schemas
161
+ end
162
+
163
+ # Loads a single tool schema from its JSON view template.
164
+ #
165
+ # @param tool_name [Symbol, String] name of the tool
166
+ # @return [Hash] tool schema with symbolized keys
167
+ # @raise [ActionView::MissingTemplate] if template not found
168
+ # @raise [JSON::ParserError] if template produces invalid JSON
169
+ def load_tool_schema(tool_name)
170
+ template_path = "tools/#{tool_name}"
171
+
172
+ json_content = render_to_string(
173
+ template: "#{agent_name}/#{template_path}",
174
+ formats: [:json],
175
+ layout: false
176
+ )
177
+
178
+ JSON.parse(json_content, symbolize_names: true)
179
+ rescue JSON::ParserError => e
180
+ Rails.logger.error "[#{self.class.name}] Invalid JSON in tool template: #{template_path}"
181
+ raise e
182
+ end
183
+
184
+ # DSL builder for inline tool definitions.
185
+ #
186
+ # Provides a clean API for defining tool schemas programmatically:
187
+ #
188
+ # tool :my_tool do
189
+ # description "Does something useful"
190
+ # parameter :input, type: :string, required: true
191
+ # end
192
+ class ToolBuilder
193
+ def initialize(name)
194
+ @name = name.to_s
195
+ @description = ""
196
+ @parameters = {}
197
+ @required = []
198
+ end
199
+
200
+ # Sets the tool description.
201
+ #
202
+ # @param text [String] human-readable description of what the tool does
203
+ # @return [void]
204
+ def description(text)
205
+ @description = text
206
+ end
207
+
208
+ # Defines a parameter for the tool.
209
+ #
210
+ # @param name [Symbol, String] parameter name
211
+ # @param type [Symbol, String] JSON Schema type (:string, :integer, :boolean, :array, :object)
212
+ # @param required [Boolean] whether this parameter is required (default: false)
213
+ # @param description [String] parameter description
214
+ # @param enum [Array] allowed values (for string type)
215
+ # @param items [Hash] item schema (for array type)
216
+ # @param properties [Hash] nested properties (for object type)
217
+ # @param default [Object] default value
218
+ # @return [void]
219
+ #
220
+ # @example Simple string parameter
221
+ # parameter :query, type: :string, required: true
222
+ #
223
+ # @example Enum parameter
224
+ # parameter :format, type: :string, enum: %w[json xml csv]
225
+ #
226
+ # @example Array parameter
227
+ # parameter :tags, type: :array, items: { type: :string }
228
+ def parameter(name, type:, required: false, description: nil, enum: nil, items: nil, properties: nil, default: nil)
229
+ param_schema = { type: type.to_s }
230
+ param_schema[:description] = description if description
231
+ param_schema[:enum] = enum if enum
232
+ param_schema[:items] = items if items
233
+ param_schema[:properties] = properties if properties
234
+ param_schema[:default] = default if default
235
+
236
+ @parameters[name.to_s] = param_schema
237
+ @required << name.to_s if required
238
+ end
239
+
240
+ # Converts the builder state to an OpenAI-compatible tool schema.
241
+ #
242
+ # @return [Hash] tool schema
243
+ def to_schema
244
+ {
245
+ type: "function",
246
+ name: @name,
247
+ description: @description,
248
+ parameters: {
249
+ type: "object",
250
+ properties: @parameters,
251
+ required: @required
252
+ }.compact
253
+ }
254
+ end
255
+ end
256
+ end
257
+ end
@@ -0,0 +1,178 @@
1
+ # frozen_string_literal: true
2
+
3
+ # StreamsToolUpdates provides real-time UI feedback during tool execution.
4
+ #
5
+ # When an agent is processing and calls tools (which may take time), this concern
6
+ # broadcasts status updates to the client so users see what's happening rather than
7
+ # a frozen UI. This is especially important for long-running tools like web browsing.
8
+ #
9
+ # @example Basic usage
10
+ # class MyAgent < ApplicationAgent
11
+ # include SolidAgent::HasTools
12
+ # include SolidAgent::StreamsToolUpdates
13
+ #
14
+ # has_tools :search, :navigate
15
+ #
16
+ # def research
17
+ # prompt(tools: tools)
18
+ # end
19
+ # end
20
+ #
21
+ # @example With custom descriptions
22
+ # class MyAgent < ApplicationAgent
23
+ # include SolidAgent::HasTools
24
+ # include SolidAgent::StreamsToolUpdates
25
+ #
26
+ # tool_description :navigate, ->(args) { "Visiting #{args[:url]}..." }
27
+ # tool_description :search, ->(args) { "Searching for '#{args[:query]}'..." }
28
+ # tool_description :extract_text, "Reading page content..."
29
+ # end
30
+ module SolidAgent
31
+ module StreamsToolUpdates
32
+ extend ActiveSupport::Concern
33
+
34
+ included do
35
+ class_attribute :_tool_descriptions, default: {}
36
+ class_attribute :_wrapped_tools, default: Set.new
37
+ end
38
+
39
+ class_methods do
40
+ # Defines a human-readable description for a tool that will be shown in the UI.
41
+ #
42
+ # @param tool_name [Symbol, String] the tool method name
43
+ # @param description [String, Proc] static string or proc that receives args
44
+ #
45
+ # @example Static description
46
+ # tool_description :extract_text, "Reading page content..."
47
+ #
48
+ # @example Dynamic description with args
49
+ # tool_description :navigate, ->(args) { "Visiting #{args[:url]}..." }
50
+ def tool_description(tool_name, description)
51
+ self._tool_descriptions = _tool_descriptions.merge(tool_name.to_sym => description)
52
+ wrap_tool_method(tool_name)
53
+ end
54
+
55
+ # Wraps a tool method to broadcast status before execution
56
+ #
57
+ # @param tool_name [Symbol, String] the tool method name
58
+ def wrap_tool_method(tool_name)
59
+ tool_sym = tool_name.to_sym
60
+ return if _wrapped_tools.include?(tool_sym)
61
+
62
+ self._wrapped_tools = _wrapped_tools.dup.add(tool_sym)
63
+
64
+ # Use prepend to wrap the method
65
+ wrapper_module = Module.new do
66
+ define_method(tool_sym) do |**kwargs|
67
+ broadcast_tool_status(tool_sym, kwargs) if should_broadcast_tools?
68
+ super(**kwargs)
69
+ end
70
+ end
71
+
72
+ prepend wrapper_module
73
+ end
74
+ end
75
+
76
+ private
77
+
78
+ def should_broadcast_tools?
79
+ params[:stream_id].present?
80
+ end
81
+
82
+ # Broadcasts a tool status update to the client
83
+ #
84
+ # @param tool_name [String, Symbol] the tool being executed
85
+ # @param args [Hash] the arguments passed to the tool
86
+ def broadcast_tool_status(tool_name, args = {})
87
+ return unless params[:stream_id]
88
+
89
+ description = tool_description_for(tool_name, args)
90
+
91
+ Rails.logger.info "[#{self.class.name}] Tool status: #{description}"
92
+
93
+ ActionCable.server.broadcast(
94
+ params[:stream_id],
95
+ {
96
+ tool_status: {
97
+ name: tool_name.to_s,
98
+ description: description,
99
+ timestamp: Time.current.iso8601
100
+ }
101
+ }
102
+ )
103
+ end
104
+
105
+ # Gets the human-readable description for a tool
106
+ #
107
+ # @param tool_name [String, Symbol] the tool name
108
+ # @param args [Hash] the arguments passed to the tool
109
+ # @return [String] description to show in UI
110
+ def tool_description_for(tool_name, args = {})
111
+ custom = _tool_descriptions[tool_name.to_sym]
112
+
113
+ if custom.is_a?(Proc)
114
+ custom.call(args)
115
+ elsif custom.is_a?(String)
116
+ custom
117
+ else
118
+ default_tool_description(tool_name, args)
119
+ end
120
+ end
121
+
122
+ # Generates a default description for common tool types
123
+ #
124
+ # @param tool_name [String, Symbol] the tool name
125
+ # @param args [Hash] the arguments passed to the tool
126
+ # @return [String] default description
127
+ def default_tool_description(tool_name, args = {})
128
+ case tool_name.to_s
129
+ when "navigate"
130
+ args[:url] ? "Visiting #{truncate_url(args[:url])}..." : "Navigating to page..."
131
+ when "click"
132
+ args[:text] ? "Clicking '#{args[:text]}'..." : "Clicking element..."
133
+ when "fill_form"
134
+ args[:field] ? "Filling in #{args[:field]}..." : "Filling form..."
135
+ when "extract_text", "extract_main_content"
136
+ "Reading page content..."
137
+ when "extract_links"
138
+ "Extracting links..."
139
+ when "page_info"
140
+ "Getting page info..."
141
+ when "go_back"
142
+ "Going back..."
143
+ when "search", "web_search"
144
+ args[:query] ? "Searching for '#{args[:query]}'..." : "Searching..."
145
+ when "read", "read_file"
146
+ args[:path] ? "Reading #{File.basename(args[:path])}..." : "Reading file..."
147
+ when "write", "write_file"
148
+ args[:path] ? "Writing #{File.basename(args[:path])}..." : "Writing file..."
149
+ else
150
+ "Performing #{tool_name.to_s.tr('_', ' ')}..."
151
+ end
152
+ end
153
+
154
+ # Truncates a URL for display
155
+ #
156
+ # @param url [String] the URL to truncate
157
+ # @param max_length [Integer] maximum length
158
+ # @return [String] truncated URL
159
+ def truncate_url(url, max_length: 50)
160
+ return url if url.length <= max_length
161
+
162
+ uri = URI.parse(url)
163
+ host = uri.host || url[0..max_length]
164
+ path = uri.path || ""
165
+
166
+ if host.length > max_length
167
+ "#{host[0..max_length]}..."
168
+ elsif (host.length + path.length) > max_length
169
+ remaining = max_length - host.length - 3
170
+ "#{host}#{path[0..remaining]}..."
171
+ else
172
+ "#{host}#{path}"
173
+ end
174
+ rescue URI::InvalidURIError
175
+ url.length > max_length ? "#{url[0..max_length]}..." : url
176
+ end
177
+ end
178
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module SolidAgent
4
+ VERSION = "0.1.1"
5
+ end
data/lib/solid_agent.rb CHANGED
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "solid_agent/version"
4
+ require_relative "solid_agent/has_context"
5
+ require_relative "solid_agent/has_tools"
6
+ require_relative "solid_agent/streams_tool_updates"
7
+
8
+ module SolidAgent
9
+ class Error < StandardError; end
10
+
11
+ class << self
12
+ attr_accessor :context_class, :message_class, :generation_class
13
+
14
+ def configure
15
+ yield self if block_given?
16
+ end
17
+ end
18
+
19
+ # Default configuration
20
+ self.context_class = "AgentContext"
21
+ self.message_class = "AgentMessage"
22
+ self.generation_class = "AgentGeneration"
23
+ end
24
+
25
+ # Load Rails integration if Rails is present
26
+ if defined?(Rails::Engine)
27
+ require_relative "solid_agent/engine"
28
+ end
@@ -0,0 +1,4 @@
1
+ module SolidAgent
2
+ VERSION: String
3
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
4
+ end
metadata CHANGED
@@ -1,27 +1,102 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solid_agent
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Justin Bowen
8
- autorequire:
9
- bindir: bin
8
+ bindir: exe
10
9
  cert_chain: []
11
- date: 2024-05-29 00:00:00.000000000 Z
12
- dependencies: []
13
- description: A simple way to make Ruby AI Agents
14
- email: jusbowen@gmail.com
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: activeagent
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: 1.0.0
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: 1.0.0
26
+ - !ruby/object:Gem::Dependency
27
+ name: activesupport
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '7.0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '7.0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: activerecord
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '7.0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '7.0'
54
+ description: SolidAgent extends ActiveAgent with database-backed prompt context management,
55
+ declarative tool schemas, and real-time streaming updates. Provides has_context,
56
+ has_tools, and streams_tool_updates concerns for building robust AI agents.
57
+ email:
58
+ - JusBowen@gmail.com
15
59
  executables: []
16
60
  extensions: []
17
61
  extra_rdoc_files: []
18
62
  files:
63
+ - README.md
64
+ - Rakefile
65
+ - lib/generators/solid_agent/agent/agent_generator.rb
66
+ - lib/generators/solid_agent/agent/templates/action.text.erb
67
+ - lib/generators/solid_agent/agent/templates/agent.rb.erb
68
+ - lib/generators/solid_agent/context/context_generator.rb
69
+ - lib/generators/solid_agent/context/templates/context_model.rb.erb
70
+ - lib/generators/solid_agent/context/templates/create_context.rb.erb
71
+ - lib/generators/solid_agent/context/templates/create_generations.rb.erb
72
+ - lib/generators/solid_agent/context/templates/create_messages.rb.erb
73
+ - lib/generators/solid_agent/context/templates/generation_model.rb.erb
74
+ - lib/generators/solid_agent/context/templates/message_model.rb.erb
75
+ - lib/generators/solid_agent/install/install_generator.rb
76
+ - lib/generators/solid_agent/install/templates/agent_context.rb.erb
77
+ - lib/generators/solid_agent/install/templates/agent_generation.rb.erb
78
+ - lib/generators/solid_agent/install/templates/agent_message.rb.erb
79
+ - lib/generators/solid_agent/install/templates/create_agent_contexts.rb.erb
80
+ - lib/generators/solid_agent/install/templates/create_agent_generations.rb.erb
81
+ - lib/generators/solid_agent/install/templates/create_agent_messages.rb.erb
82
+ - lib/generators/solid_agent/install/templates/initializer.rb.erb
83
+ - lib/generators/solid_agent/tool/templates/tool.json.erb
84
+ - lib/generators/solid_agent/tool/tool_generator.rb
19
85
  - lib/solid_agent.rb
20
- homepage: https://rubygems.org/gems/solid_eagent
86
+ - lib/solid_agent/engine.rb
87
+ - lib/solid_agent/has_context.rb
88
+ - lib/solid_agent/has_tools.rb
89
+ - lib/solid_agent/streams_tool_updates.rb
90
+ - lib/solid_agent/version.rb
91
+ - sig/solid_agent.rbs
92
+ homepage: https://docs.activeagents.ai/solid_agent
21
93
  licenses:
22
94
  - MIT
23
- metadata: {}
24
- post_install_message:
95
+ metadata:
96
+ homepage_uri: https://docs.activeagents.ai/solid_agent
97
+ source_code_uri: https://github.com/activeagents/solid_agent
98
+ changelog_uri: https://github.com/activeagents/solid_agent/blob/main/CHANGELOG.md
99
+ documentation_uri: https://docs.activeagents.ai/solid_agent
25
100
  rdoc_options: []
26
101
  require_paths:
27
102
  - lib
@@ -29,15 +104,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
29
104
  requirements:
30
105
  - - ">="
31
106
  - !ruby/object:Gem::Version
32
- version: '0'
107
+ version: 3.0.0
33
108
  required_rubygems_version: !ruby/object:Gem::Requirement
34
109
  requirements:
35
110
  - - ">="
36
111
  - !ruby/object:Gem::Version
37
112
  version: '0'
38
113
  requirements: []
39
- rubygems_version: 3.5.3
40
- signing_key:
114
+ rubygems_version: 3.7.2
41
115
  specification_version: 4
42
- summary: A simple way to make Ruby AI Agents
116
+ summary: Database-backed context, tools, and streaming for ActiveAgent
43
117
  test_files: []