ruby_llm-agents 0.1.0
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 +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +898 -0
- data/app/channels/ruby_llm/agents/executions_channel.rb +23 -0
- data/app/controllers/ruby_llm/agents/agents_controller.rb +100 -0
- data/app/controllers/ruby_llm/agents/application_controller.rb +20 -0
- data/app/controllers/ruby_llm/agents/dashboard_controller.rb +34 -0
- data/app/controllers/ruby_llm/agents/executions_controller.rb +93 -0
- data/app/helpers/ruby_llm/agents/application_helper.rb +149 -0
- data/app/javascript/ruby_llm/agents/controllers/filter_controller.js +56 -0
- data/app/javascript/ruby_llm/agents/controllers/index.js +12 -0
- data/app/javascript/ruby_llm/agents/controllers/refresh_controller.js +83 -0
- data/app/models/ruby_llm/agents/execution/analytics.rb +166 -0
- data/app/models/ruby_llm/agents/execution/metrics.rb +89 -0
- data/app/models/ruby_llm/agents/execution/scopes.rb +81 -0
- data/app/models/ruby_llm/agents/execution.rb +81 -0
- data/app/services/ruby_llm/agents/agent_registry.rb +112 -0
- data/app/views/layouts/rubyllm/agents/application.html.erb +276 -0
- data/app/views/rubyllm/agents/agents/index.html.erb +89 -0
- data/app/views/rubyllm/agents/agents/show.html.erb +562 -0
- data/app/views/rubyllm/agents/dashboard/_execution_item.html.erb +48 -0
- data/app/views/rubyllm/agents/dashboard/index.html.erb +121 -0
- data/app/views/rubyllm/agents/executions/_execution.html.erb +64 -0
- data/app/views/rubyllm/agents/executions/_filters.html.erb +172 -0
- data/app/views/rubyllm/agents/executions/_list.html.erb +229 -0
- data/app/views/rubyllm/agents/executions/index.html.erb +83 -0
- data/app/views/rubyllm/agents/executions/index.turbo_stream.erb +4 -0
- data/app/views/rubyllm/agents/executions/show.html.erb +240 -0
- data/app/views/rubyllm/agents/shared/_executions_table.html.erb +193 -0
- data/app/views/rubyllm/agents/shared/_stat_card.html.erb +14 -0
- data/app/views/rubyllm/agents/shared/_status_badge.html.erb +65 -0
- data/app/views/rubyllm/agents/shared/_status_dot.html.erb +18 -0
- data/config/routes.rb +13 -0
- data/lib/generators/ruby_llm_agents/agent_generator.rb +79 -0
- data/lib/generators/ruby_llm_agents/install_generator.rb +89 -0
- data/lib/generators/ruby_llm_agents/templates/add_prompts_migration.rb.tt +12 -0
- data/lib/generators/ruby_llm_agents/templates/agent.rb.tt +46 -0
- data/lib/generators/ruby_llm_agents/templates/application_agent.rb.tt +22 -0
- data/lib/generators/ruby_llm_agents/templates/initializer.rb.tt +36 -0
- data/lib/generators/ruby_llm_agents/templates/migration.rb.tt +66 -0
- data/lib/generators/ruby_llm_agents/upgrade_generator.rb +59 -0
- data/lib/ruby_llm/agents/base.rb +271 -0
- data/lib/ruby_llm/agents/configuration.rb +36 -0
- data/lib/ruby_llm/agents/engine.rb +32 -0
- data/lib/ruby_llm/agents/execution_logger_job.rb +59 -0
- data/lib/ruby_llm/agents/inflections.rb +13 -0
- data/lib/ruby_llm/agents/instrumentation.rb +245 -0
- data/lib/ruby_llm/agents/version.rb +7 -0
- data/lib/ruby_llm/agents.rb +26 -0
- data/lib/ruby_llm-agents.rb +3 -0
- metadata +164 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Agents
|
|
5
|
+
class Configuration
|
|
6
|
+
attr_accessor :default_model,
|
|
7
|
+
:default_temperature,
|
|
8
|
+
:default_timeout,
|
|
9
|
+
:async_logging,
|
|
10
|
+
:retention_period,
|
|
11
|
+
:anomaly_cost_threshold,
|
|
12
|
+
:anomaly_duration_threshold,
|
|
13
|
+
:dashboard_auth,
|
|
14
|
+
:dashboard_parent_controller
|
|
15
|
+
|
|
16
|
+
attr_writer :cache_store
|
|
17
|
+
|
|
18
|
+
def initialize
|
|
19
|
+
@default_model = "gemini-2.0-flash"
|
|
20
|
+
@default_temperature = 0.0
|
|
21
|
+
@default_timeout = 60
|
|
22
|
+
@cache_store = nil
|
|
23
|
+
@async_logging = true
|
|
24
|
+
@retention_period = 30.days
|
|
25
|
+
@anomaly_cost_threshold = 5.00
|
|
26
|
+
@anomaly_duration_threshold = 10_000
|
|
27
|
+
@dashboard_auth = ->(_controller) { true }
|
|
28
|
+
@dashboard_parent_controller = "ActionController::Base"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def cache_store
|
|
32
|
+
@cache_store || Rails.cache
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Agents
|
|
5
|
+
class Engine < ::Rails::Engine
|
|
6
|
+
isolate_namespace RubyLLM::Agents
|
|
7
|
+
|
|
8
|
+
# Use to_prepare to load classes after autoloading is set up
|
|
9
|
+
# This ensures app/models are available when referenced
|
|
10
|
+
config.to_prepare do
|
|
11
|
+
require_relative "execution_logger_job"
|
|
12
|
+
require_relative "instrumentation"
|
|
13
|
+
require_relative "base"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Configure generators
|
|
17
|
+
config.generators do |g|
|
|
18
|
+
g.test_framework :rspec
|
|
19
|
+
g.fixture_replacement :factory_bot
|
|
20
|
+
g.factory_bot dir: "spec/factories"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Add app/agents to autoload paths for host app (must be done before initialization)
|
|
24
|
+
initializer "ruby_llm_agents.autoload_agents", before: :set_autoload_paths do |app|
|
|
25
|
+
agents_path = app.root.join("app/agents")
|
|
26
|
+
if agents_path.exist?
|
|
27
|
+
Rails.autoloaders.main.push_dir(agents_path.to_s)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Agents
|
|
5
|
+
# Background job for logging agent executions to the database
|
|
6
|
+
#
|
|
7
|
+
# This job is called automatically after each agent execution to:
|
|
8
|
+
# - Create an Execution record with all execution data
|
|
9
|
+
# - Calculate costs based on token usage
|
|
10
|
+
# - Log anomalies (expensive, slow, or failed executions)
|
|
11
|
+
#
|
|
12
|
+
# Configuration:
|
|
13
|
+
# RubyLLM::Agents.configure do |config|
|
|
14
|
+
# config.anomaly_cost_threshold = 5.00 # Log if cost > $5
|
|
15
|
+
# config.anomaly_duration_threshold = 10_000 # Log if duration > 10s
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
class ExecutionLoggerJob < ActiveJob::Base
|
|
19
|
+
queue_as :default
|
|
20
|
+
|
|
21
|
+
# Retry with polynomial backoff
|
|
22
|
+
retry_on StandardError, wait: :polynomially_longer, attempts: 3
|
|
23
|
+
|
|
24
|
+
def perform(execution_data)
|
|
25
|
+
execution = Execution.create!(execution_data)
|
|
26
|
+
|
|
27
|
+
# Calculate costs if token data is available
|
|
28
|
+
if execution.input_tokens && execution.output_tokens
|
|
29
|
+
execution.calculate_costs!
|
|
30
|
+
execution.save!
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Log if execution was anomalous
|
|
34
|
+
log_anomaly(execution) if anomaly?(execution)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def anomaly?(execution)
|
|
40
|
+
config = RubyLLM::Agents.configuration
|
|
41
|
+
|
|
42
|
+
(execution.total_cost && execution.total_cost > config.anomaly_cost_threshold) ||
|
|
43
|
+
(execution.duration_ms && execution.duration_ms > config.anomaly_duration_threshold) ||
|
|
44
|
+
execution.status_error?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def log_anomaly(execution)
|
|
48
|
+
Rails.logger.warn(
|
|
49
|
+
"[RubyLLM::Agents] Execution anomaly detected: " \
|
|
50
|
+
"agent=#{execution.agent_type} " \
|
|
51
|
+
"id=#{execution.id} " \
|
|
52
|
+
"cost=$#{execution.total_cost} " \
|
|
53
|
+
"duration_ms=#{execution.duration_ms} " \
|
|
54
|
+
"status=#{execution.status}"
|
|
55
|
+
)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Configure acronym for Rails inflector (used in routes)
|
|
4
|
+
ActiveSupport::Inflector.inflections(:en) do |inflect|
|
|
5
|
+
inflect.acronym "LLM"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Configure Zeitwerk inflection when autoloaders are available
|
|
9
|
+
ActiveSupport.on_load(:before_configuration) do
|
|
10
|
+
Rails.autoloaders.each do |autoloader|
|
|
11
|
+
autoloader.inflector.inflect("ruby_llm" => "RubyLLM")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Agents
|
|
5
|
+
# Instrumentation concern for tracking agent executions
|
|
6
|
+
#
|
|
7
|
+
# Provides execution timing, token tracking, cost calculation, and error handling.
|
|
8
|
+
# Logs all executions to the database via a background job.
|
|
9
|
+
#
|
|
10
|
+
# == Usage
|
|
11
|
+
#
|
|
12
|
+
# Included automatically in RubyLLM::Agents::Base
|
|
13
|
+
#
|
|
14
|
+
# == Customization
|
|
15
|
+
#
|
|
16
|
+
# Override `execution_metadata` in your agent to add custom data:
|
|
17
|
+
#
|
|
18
|
+
# def execution_metadata
|
|
19
|
+
# { query: query, user_id: Current.user&.id }
|
|
20
|
+
# end
|
|
21
|
+
#
|
|
22
|
+
module Instrumentation
|
|
23
|
+
extend ActiveSupport::Concern
|
|
24
|
+
|
|
25
|
+
included do
|
|
26
|
+
attr_accessor :execution_id
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Wrap agent execution with metrics tracking
|
|
30
|
+
# Creates execution record at start with 'running' status, updates on completion
|
|
31
|
+
def instrument_execution(&block)
|
|
32
|
+
started_at = Time.current
|
|
33
|
+
@last_response = nil
|
|
34
|
+
|
|
35
|
+
# Create execution record immediately with running status
|
|
36
|
+
execution = create_running_execution(started_at)
|
|
37
|
+
self.execution_id = execution&.id
|
|
38
|
+
|
|
39
|
+
begin
|
|
40
|
+
result = yield
|
|
41
|
+
|
|
42
|
+
# Update to success
|
|
43
|
+
complete_execution(
|
|
44
|
+
execution,
|
|
45
|
+
completed_at: Time.current,
|
|
46
|
+
status: "success",
|
|
47
|
+
response: @last_response
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
result
|
|
51
|
+
rescue Timeout::Error => e
|
|
52
|
+
complete_execution(
|
|
53
|
+
execution,
|
|
54
|
+
completed_at: Time.current,
|
|
55
|
+
status: "timeout",
|
|
56
|
+
error: e
|
|
57
|
+
)
|
|
58
|
+
raise
|
|
59
|
+
rescue => e
|
|
60
|
+
complete_execution(
|
|
61
|
+
execution,
|
|
62
|
+
completed_at: Time.current,
|
|
63
|
+
status: "error",
|
|
64
|
+
error: e
|
|
65
|
+
)
|
|
66
|
+
raise
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Store response for metrics extraction
|
|
71
|
+
def capture_response(response)
|
|
72
|
+
@last_response = response
|
|
73
|
+
response
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
private
|
|
77
|
+
|
|
78
|
+
# Create execution record with running status at start
|
|
79
|
+
def create_running_execution(started_at)
|
|
80
|
+
execution_data = {
|
|
81
|
+
agent_type: self.class.name,
|
|
82
|
+
agent_version: self.class.version,
|
|
83
|
+
model_id: model,
|
|
84
|
+
temperature: temperature,
|
|
85
|
+
started_at: started_at,
|
|
86
|
+
status: "running",
|
|
87
|
+
parameters: sanitized_parameters,
|
|
88
|
+
metadata: execution_metadata,
|
|
89
|
+
system_prompt: safe_system_prompt,
|
|
90
|
+
user_prompt: safe_user_prompt
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
RubyLLM::Agents::Execution.create!(execution_data)
|
|
94
|
+
rescue StandardError => e
|
|
95
|
+
# Log error but don't fail the execution
|
|
96
|
+
Rails.logger.error("[RubyLLM::Agents] Failed to create execution record: #{e.message}")
|
|
97
|
+
nil
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Update execution record on completion
|
|
101
|
+
def complete_execution(execution, completed_at:, status:, response: nil, error: nil)
|
|
102
|
+
return legacy_log_execution(completed_at: completed_at, status: status, response: response, error: error) unless execution
|
|
103
|
+
|
|
104
|
+
started_at = execution.started_at
|
|
105
|
+
duration_ms = ((completed_at - started_at) * 1000).round
|
|
106
|
+
|
|
107
|
+
update_data = {
|
|
108
|
+
completed_at: completed_at,
|
|
109
|
+
duration_ms: duration_ms,
|
|
110
|
+
status: status
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
# Add response data if available
|
|
114
|
+
if response.is_a?(RubyLLM::Message)
|
|
115
|
+
update_data.merge!(
|
|
116
|
+
input_tokens: response.input_tokens,
|
|
117
|
+
output_tokens: response.output_tokens,
|
|
118
|
+
cached_tokens: response.cached_tokens || 0,
|
|
119
|
+
cache_creation_tokens: response.cache_creation_tokens || 0,
|
|
120
|
+
model_id: response.model_id || model,
|
|
121
|
+
response: serialize_response(response)
|
|
122
|
+
)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
# Add error data if failed
|
|
126
|
+
if error
|
|
127
|
+
update_data.merge!(
|
|
128
|
+
error_message: error.message,
|
|
129
|
+
error_class: error.class.name
|
|
130
|
+
)
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
execution.update!(update_data)
|
|
134
|
+
|
|
135
|
+
# Calculate costs if token data is available
|
|
136
|
+
if execution.input_tokens && execution.output_tokens
|
|
137
|
+
execution.calculate_costs!
|
|
138
|
+
execution.save!
|
|
139
|
+
end
|
|
140
|
+
rescue StandardError => e
|
|
141
|
+
Rails.logger.error("[RubyLLM::Agents] Failed to update execution record: #{e.message}")
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Fallback for when initial execution creation failed
|
|
145
|
+
def legacy_log_execution(completed_at:, status:, response: nil, error: nil)
|
|
146
|
+
execution_data = {
|
|
147
|
+
agent_type: self.class.name,
|
|
148
|
+
agent_version: self.class.version,
|
|
149
|
+
model_id: model,
|
|
150
|
+
temperature: temperature,
|
|
151
|
+
started_at: Time.current,
|
|
152
|
+
completed_at: completed_at,
|
|
153
|
+
duration_ms: 0,
|
|
154
|
+
status: status,
|
|
155
|
+
parameters: sanitized_parameters,
|
|
156
|
+
metadata: execution_metadata,
|
|
157
|
+
system_prompt: safe_system_prompt,
|
|
158
|
+
user_prompt: safe_user_prompt
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if response.is_a?(RubyLLM::Message)
|
|
162
|
+
execution_data.merge!(
|
|
163
|
+
input_tokens: response.input_tokens,
|
|
164
|
+
output_tokens: response.output_tokens,
|
|
165
|
+
cached_tokens: response.cached_tokens || 0,
|
|
166
|
+
cache_creation_tokens: response.cache_creation_tokens || 0,
|
|
167
|
+
model_id: response.model_id || model,
|
|
168
|
+
response: serialize_response(response)
|
|
169
|
+
)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
if error
|
|
173
|
+
execution_data.merge!(
|
|
174
|
+
error_message: error.message,
|
|
175
|
+
error_class: error.class.name
|
|
176
|
+
)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
if RubyLLM::Agents.configuration.async_logging
|
|
180
|
+
RubyLLM::Agents::ExecutionLoggerJob.perform_later(execution_data)
|
|
181
|
+
else
|
|
182
|
+
RubyLLM::Agents::ExecutionLoggerJob.new.perform(execution_data)
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
# Sanitize parameters to remove sensitive data
|
|
187
|
+
def sanitized_parameters
|
|
188
|
+
params = @options.dup
|
|
189
|
+
|
|
190
|
+
# Remove sensitive keys
|
|
191
|
+
sensitive_keys = %i[password token api_key secret credential auth key]
|
|
192
|
+
sensitive_keys.each { |key| params.delete(key) }
|
|
193
|
+
|
|
194
|
+
# Convert ActiveRecord objects to IDs
|
|
195
|
+
params.transform_values do |value|
|
|
196
|
+
case value
|
|
197
|
+
when defined?(ActiveRecord::Base) && ActiveRecord::Base
|
|
198
|
+
{ id: value.id, type: value.class.name }
|
|
199
|
+
when Array
|
|
200
|
+
if value.first.is_a?(ActiveRecord::Base)
|
|
201
|
+
{ ids: value.first(10).map(&:id), type: value.first.class.name, count: value.size }
|
|
202
|
+
else
|
|
203
|
+
value.first(10)
|
|
204
|
+
end
|
|
205
|
+
else
|
|
206
|
+
value
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Serialize full RubyLLM::Message response to JSON
|
|
212
|
+
def serialize_response(response)
|
|
213
|
+
{
|
|
214
|
+
content: response.content,
|
|
215
|
+
model_id: response.model_id,
|
|
216
|
+
input_tokens: response.input_tokens,
|
|
217
|
+
output_tokens: response.output_tokens,
|
|
218
|
+
cached_tokens: response.cached_tokens,
|
|
219
|
+
cache_creation_tokens: response.cache_creation_tokens
|
|
220
|
+
}.compact
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Hook for subclasses to add custom metadata
|
|
224
|
+
def execution_metadata
|
|
225
|
+
{}
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
# Safely capture system prompt (may raise or return nil)
|
|
229
|
+
def safe_system_prompt
|
|
230
|
+
respond_to?(:system_prompt) ? system_prompt.to_s : nil
|
|
231
|
+
rescue StandardError => e
|
|
232
|
+
Rails.logger.warn("[RubyLLM::Agents] Could not capture system_prompt: #{e.message}")
|
|
233
|
+
nil
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# Safely capture user prompt (may raise or return nil)
|
|
237
|
+
def safe_user_prompt
|
|
238
|
+
respond_to?(:user_prompt) ? user_prompt.to_s : nil
|
|
239
|
+
rescue StandardError => e
|
|
240
|
+
Rails.logger.warn("[RubyLLM::Agents] Could not capture user_prompt: #{e.message}")
|
|
241
|
+
nil
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "agents/version"
|
|
4
|
+
require_relative "agents/configuration"
|
|
5
|
+
require_relative "agents/inflections" if defined?(Rails)
|
|
6
|
+
require_relative "agents/engine" if defined?(Rails::Engine)
|
|
7
|
+
|
|
8
|
+
module RubyLLM
|
|
9
|
+
module Agents
|
|
10
|
+
class Error < StandardError; end
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
def configuration
|
|
14
|
+
@configuration ||= Configuration.new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def configure
|
|
18
|
+
yield(configuration)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def reset_configuration!
|
|
22
|
+
@configuration = Configuration.new
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ruby_llm-agents
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- adham90
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rails
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '7.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '7.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: ruby_llm
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - ">="
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '1.0'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '1.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: turbo-rails
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - ">="
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.0'
|
|
47
|
+
type: :runtime
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: stimulus-rails
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - ">="
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '1.0'
|
|
61
|
+
type: :runtime
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - ">="
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '1.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: chartkick
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - ">="
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '5.0'
|
|
75
|
+
type: :runtime
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - ">="
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '5.0'
|
|
82
|
+
description: A Rails engine for creating, managing, and monitoring LLM-powered agents.
|
|
83
|
+
Includes a DSL for agent configuration, execution tracking, cost analytics, and
|
|
84
|
+
a mountable dashboard UI.
|
|
85
|
+
email:
|
|
86
|
+
- hi@adham.dev
|
|
87
|
+
executables: []
|
|
88
|
+
extensions: []
|
|
89
|
+
extra_rdoc_files: []
|
|
90
|
+
files:
|
|
91
|
+
- LICENSE.txt
|
|
92
|
+
- README.md
|
|
93
|
+
- app/channels/ruby_llm/agents/executions_channel.rb
|
|
94
|
+
- app/controllers/ruby_llm/agents/agents_controller.rb
|
|
95
|
+
- app/controllers/ruby_llm/agents/application_controller.rb
|
|
96
|
+
- app/controllers/ruby_llm/agents/dashboard_controller.rb
|
|
97
|
+
- app/controllers/ruby_llm/agents/executions_controller.rb
|
|
98
|
+
- app/helpers/ruby_llm/agents/application_helper.rb
|
|
99
|
+
- app/javascript/ruby_llm/agents/controllers/filter_controller.js
|
|
100
|
+
- app/javascript/ruby_llm/agents/controllers/index.js
|
|
101
|
+
- app/javascript/ruby_llm/agents/controllers/refresh_controller.js
|
|
102
|
+
- app/models/ruby_llm/agents/execution.rb
|
|
103
|
+
- app/models/ruby_llm/agents/execution/analytics.rb
|
|
104
|
+
- app/models/ruby_llm/agents/execution/metrics.rb
|
|
105
|
+
- app/models/ruby_llm/agents/execution/scopes.rb
|
|
106
|
+
- app/services/ruby_llm/agents/agent_registry.rb
|
|
107
|
+
- app/views/layouts/rubyllm/agents/application.html.erb
|
|
108
|
+
- app/views/rubyllm/agents/agents/index.html.erb
|
|
109
|
+
- app/views/rubyllm/agents/agents/show.html.erb
|
|
110
|
+
- app/views/rubyllm/agents/dashboard/_execution_item.html.erb
|
|
111
|
+
- app/views/rubyllm/agents/dashboard/index.html.erb
|
|
112
|
+
- app/views/rubyllm/agents/executions/_execution.html.erb
|
|
113
|
+
- app/views/rubyllm/agents/executions/_filters.html.erb
|
|
114
|
+
- app/views/rubyllm/agents/executions/_list.html.erb
|
|
115
|
+
- app/views/rubyllm/agents/executions/index.html.erb
|
|
116
|
+
- app/views/rubyllm/agents/executions/index.turbo_stream.erb
|
|
117
|
+
- app/views/rubyllm/agents/executions/show.html.erb
|
|
118
|
+
- app/views/rubyllm/agents/shared/_executions_table.html.erb
|
|
119
|
+
- app/views/rubyllm/agents/shared/_stat_card.html.erb
|
|
120
|
+
- app/views/rubyllm/agents/shared/_status_badge.html.erb
|
|
121
|
+
- app/views/rubyllm/agents/shared/_status_dot.html.erb
|
|
122
|
+
- config/routes.rb
|
|
123
|
+
- lib/generators/ruby_llm_agents/agent_generator.rb
|
|
124
|
+
- lib/generators/ruby_llm_agents/install_generator.rb
|
|
125
|
+
- lib/generators/ruby_llm_agents/templates/add_prompts_migration.rb.tt
|
|
126
|
+
- lib/generators/ruby_llm_agents/templates/agent.rb.tt
|
|
127
|
+
- lib/generators/ruby_llm_agents/templates/application_agent.rb.tt
|
|
128
|
+
- lib/generators/ruby_llm_agents/templates/initializer.rb.tt
|
|
129
|
+
- lib/generators/ruby_llm_agents/templates/migration.rb.tt
|
|
130
|
+
- lib/generators/ruby_llm_agents/upgrade_generator.rb
|
|
131
|
+
- lib/ruby_llm-agents.rb
|
|
132
|
+
- lib/ruby_llm/agents.rb
|
|
133
|
+
- lib/ruby_llm/agents/base.rb
|
|
134
|
+
- lib/ruby_llm/agents/configuration.rb
|
|
135
|
+
- lib/ruby_llm/agents/engine.rb
|
|
136
|
+
- lib/ruby_llm/agents/execution_logger_job.rb
|
|
137
|
+
- lib/ruby_llm/agents/inflections.rb
|
|
138
|
+
- lib/ruby_llm/agents/instrumentation.rb
|
|
139
|
+
- lib/ruby_llm/agents/version.rb
|
|
140
|
+
homepage: https://github.com/adham90/ruby_llm-agents
|
|
141
|
+
licenses:
|
|
142
|
+
- MIT
|
|
143
|
+
metadata:
|
|
144
|
+
homepage_uri: https://github.com/adham90/ruby_llm-agents
|
|
145
|
+
source_code_uri: https://github.com/adham90/ruby_llm-agents
|
|
146
|
+
changelog_uri: https://github.com/adham90/ruby_llm-agents/blob/main/CHANGELOG.md
|
|
147
|
+
rdoc_options: []
|
|
148
|
+
require_paths:
|
|
149
|
+
- lib
|
|
150
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
151
|
+
requirements:
|
|
152
|
+
- - ">="
|
|
153
|
+
- !ruby/object:Gem::Version
|
|
154
|
+
version: 3.1.0
|
|
155
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - ">="
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '0'
|
|
160
|
+
requirements: []
|
|
161
|
+
rubygems_version: 3.6.9
|
|
162
|
+
specification_version: 4
|
|
163
|
+
summary: Agent framework for building LLM-powered agents with RubyLLM
|
|
164
|
+
test_files: []
|