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.
- checksums.yaml +4 -4
- data/README.md +130 -0
- data/Rakefile +12 -0
- data/lib/generators/solid_agent/agent/agent_generator.rb +95 -0
- data/lib/generators/solid_agent/agent/templates/action.text.erb +10 -0
- data/lib/generators/solid_agent/agent/templates/agent.rb.erb +93 -0
- data/lib/generators/solid_agent/context/context_generator.rb +124 -0
- data/lib/generators/solid_agent/context/templates/context_model.rb.erb +100 -0
- data/lib/generators/solid_agent/context/templates/create_context.rb.erb +32 -0
- data/lib/generators/solid_agent/context/templates/create_generations.rb.erb +38 -0
- data/lib/generators/solid_agent/context/templates/create_messages.rb.erb +33 -0
- data/lib/generators/solid_agent/context/templates/generation_model.rb.erb +40 -0
- data/lib/generators/solid_agent/context/templates/message_model.rb.erb +47 -0
- data/lib/generators/solid_agent/install/install_generator.rb +83 -0
- data/lib/generators/solid_agent/install/templates/agent_context.rb.erb +128 -0
- data/lib/generators/solid_agent/install/templates/agent_generation.rb.erb +59 -0
- data/lib/generators/solid_agent/install/templates/agent_message.rb.erb +76 -0
- data/lib/generators/solid_agent/install/templates/create_agent_contexts.rb.erb +32 -0
- data/lib/generators/solid_agent/install/templates/create_agent_generations.rb.erb +38 -0
- data/lib/generators/solid_agent/install/templates/create_agent_messages.rb.erb +33 -0
- data/lib/generators/solid_agent/install/templates/initializer.rb.erb +51 -0
- data/lib/generators/solid_agent/tool/templates/tool.json.erb +19 -0
- data/lib/generators/solid_agent/tool/tool_generator.rb +117 -0
- data/lib/solid_agent/engine.rb +16 -0
- data/lib/solid_agent/has_context.rb +449 -0
- data/lib/solid_agent/has_tools.rb +257 -0
- data/lib/solid_agent/streams_tool_updates.rb +178 -0
- data/lib/solid_agent/version.rb +5 -0
- data/lib/solid_agent.rb +28 -0
- data/sig/solid_agent.rbs +4 -0
- 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
|
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
|
data/sig/solid_agent.rbs
ADDED
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.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Justin Bowen
|
|
8
|
-
|
|
9
|
-
bindir: bin
|
|
8
|
+
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
-
dependencies:
|
|
13
|
-
|
|
14
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
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.
|
|
40
|
-
signing_key:
|
|
114
|
+
rubygems_version: 3.7.2
|
|
41
115
|
specification_version: 4
|
|
42
|
-
summary:
|
|
116
|
+
summary: Database-backed context, tools, and streaming for ActiveAgent
|
|
43
117
|
test_files: []
|