ruby_llm-agents 3.7.2 → 3.9.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 +4 -4
- data/README.md +30 -10
- data/app/controllers/ruby_llm/agents/agents_controller.rb +14 -141
- data/app/controllers/ruby_llm/agents/dashboard_controller.rb +12 -166
- data/app/controllers/ruby_llm/agents/executions_controller.rb +1 -1
- data/app/controllers/ruby_llm/agents/requests_controller.rb +117 -0
- data/app/helpers/ruby_llm/agents/application_helper.rb +38 -0
- data/app/models/ruby_llm/agents/execution/analytics.rb +302 -103
- data/app/models/ruby_llm/agents/execution.rb +76 -54
- data/app/models/ruby_llm/agents/execution_detail.rb +2 -0
- data/app/models/ruby_llm/agents/tenant.rb +39 -0
- data/app/services/ruby_llm/agents/agent_registry.rb +98 -0
- data/app/views/layouts/ruby_llm/agents/application.html.erb +4 -2
- data/app/views/ruby_llm/agents/executions/_list.html.erb +3 -17
- data/app/views/ruby_llm/agents/requests/index.html.erb +153 -0
- data/app/views/ruby_llm/agents/requests/show.html.erb +136 -0
- data/config/routes.rb +2 -0
- data/lib/generators/ruby_llm_agents/agent_generator.rb +2 -2
- data/lib/generators/ruby_llm_agents/demo_generator.rb +102 -0
- data/lib/generators/ruby_llm_agents/doctor_generator.rb +196 -0
- data/lib/generators/ruby_llm_agents/install_generator.rb +7 -19
- data/lib/generators/ruby_llm_agents/templates/add_dashboard_performance_indexes_migration.rb.tt +23 -0
- data/lib/generators/ruby_llm_agents/templates/agent.rb.tt +27 -80
- data/lib/generators/ruby_llm_agents/templates/application_agent.rb.tt +18 -51
- data/lib/generators/ruby_llm_agents/templates/initializer.rb.tt +19 -17
- data/lib/generators/ruby_llm_agents/templates/migration.rb.tt +3 -0
- data/lib/generators/ruby_llm_agents/upgrade_generator.rb +25 -0
- data/lib/ruby_llm/agents/base_agent.rb +71 -4
- data/lib/ruby_llm/agents/core/base.rb +4 -0
- data/lib/ruby_llm/agents/core/configuration.rb +11 -0
- data/lib/ruby_llm/agents/core/instrumentation.rb +15 -19
- data/lib/ruby_llm/agents/core/version.rb +1 -1
- data/lib/ruby_llm/agents/infrastructure/alert_manager.rb +4 -4
- data/lib/ruby_llm/agents/infrastructure/budget_tracker.rb +19 -11
- data/lib/ruby_llm/agents/pipeline/builder.rb +8 -4
- data/lib/ruby_llm/agents/pipeline/context.rb +69 -1
- data/lib/ruby_llm/agents/pipeline/middleware/base.rb +58 -4
- data/lib/ruby_llm/agents/pipeline/middleware/budget.rb +21 -17
- data/lib/ruby_llm/agents/pipeline/middleware/cache.rb +40 -26
- data/lib/ruby_llm/agents/pipeline/middleware/instrumentation.rb +126 -120
- data/lib/ruby_llm/agents/pipeline/middleware/reliability.rb +13 -11
- data/lib/ruby_llm/agents/pipeline/middleware/tenant.rb +29 -31
- data/lib/ruby_llm/agents/providers/inception/capabilities.rb +107 -0
- data/lib/ruby_llm/agents/providers/inception/chat.rb +17 -0
- data/lib/ruby_llm/agents/providers/inception/configuration.rb +9 -0
- data/lib/ruby_llm/agents/providers/inception/models.rb +38 -0
- data/lib/ruby_llm/agents/providers/inception/registry.rb +45 -0
- data/lib/ruby_llm/agents/providers/inception.rb +50 -0
- data/lib/ruby_llm/agents/rails/engine.rb +11 -0
- data/lib/ruby_llm/agents/results/background_removal_result.rb +7 -1
- data/lib/ruby_llm/agents/results/base.rb +28 -4
- data/lib/ruby_llm/agents/results/embedding_result.rb +4 -0
- data/lib/ruby_llm/agents/results/image_analysis_result.rb +11 -3
- data/lib/ruby_llm/agents/results/image_edit_result.rb +7 -1
- data/lib/ruby_llm/agents/results/image_generation_result.rb +7 -1
- data/lib/ruby_llm/agents/results/image_pipeline_result.rb +7 -1
- data/lib/ruby_llm/agents/results/image_transform_result.rb +7 -1
- data/lib/ruby_llm/agents/results/image_upscale_result.rb +7 -1
- data/lib/ruby_llm/agents/results/image_variation_result.rb +7 -1
- data/lib/ruby_llm/agents/results/speech_result.rb +6 -0
- data/lib/ruby_llm/agents/results/trackable.rb +25 -0
- data/lib/ruby_llm/agents/results/transcription_result.rb +6 -0
- data/lib/ruby_llm/agents/text/embedder.rb +8 -1
- data/lib/ruby_llm/agents/track_report.rb +127 -0
- data/lib/ruby_llm/agents/tracker.rb +32 -0
- data/lib/ruby_llm/agents.rb +212 -0
- data/lib/tasks/ruby_llm_agents.rake +6 -0
- metadata +17 -2
|
@@ -26,6 +26,8 @@ module RubyLLM
|
|
|
26
26
|
#
|
|
27
27
|
# @api public
|
|
28
28
|
class TranscriptionResult
|
|
29
|
+
include Trackable
|
|
30
|
+
|
|
29
31
|
# @!group Content
|
|
30
32
|
|
|
31
33
|
# @!attribute [r] text
|
|
@@ -250,6 +252,10 @@ module RubyLLM
|
|
|
250
252
|
|
|
251
253
|
# Execution record
|
|
252
254
|
@execution_id = attributes[:execution_id]
|
|
255
|
+
|
|
256
|
+
# Tracking
|
|
257
|
+
@agent_class_name = attributes[:agent_class_name]
|
|
258
|
+
register_with_tracker
|
|
253
259
|
end
|
|
254
260
|
|
|
255
261
|
# Loads the associated Execution record from the database
|
|
@@ -337,7 +337,14 @@ module RubyLLM
|
|
|
337
337
|
embed_options = {model: context&.model || resolved_model}
|
|
338
338
|
embed_options[:dimensions] = resolved_dimensions if resolved_dimensions
|
|
339
339
|
|
|
340
|
-
|
|
340
|
+
# Use scoped RubyLLM::Context for thread-safe per-tenant API keys.
|
|
341
|
+
# RubyLLM::Context#embed creates an Embedding with the scoped config.
|
|
342
|
+
llm_ctx = context&.llm
|
|
343
|
+
response = if llm_ctx.is_a?(RubyLLM::Context)
|
|
344
|
+
llm_ctx.embed(preprocessed, **embed_options)
|
|
345
|
+
else
|
|
346
|
+
RubyLLM.embed(preprocessed, **embed_options)
|
|
347
|
+
end
|
|
341
348
|
|
|
342
349
|
# ruby_llm returns vectors as an array (even for single text)
|
|
343
350
|
vectors = response.vectors
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Agents
|
|
5
|
+
# Aggregated read-only report returned by RubyLLM::Agents.track.
|
|
6
|
+
#
|
|
7
|
+
# Provides totals and breakdowns across all agent calls made
|
|
8
|
+
# inside the tracked block.
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# report = RubyLLM::Agents.track do
|
|
12
|
+
# TranscribeAgent.call(with: audio_path)
|
|
13
|
+
# ChatAgent.call(message: "hello")
|
|
14
|
+
# end
|
|
15
|
+
# report.total_cost # => 0.0078
|
|
16
|
+
# report.call_count # => 2
|
|
17
|
+
#
|
|
18
|
+
# @api public
|
|
19
|
+
class TrackReport
|
|
20
|
+
attr_reader :value, :error, :results, :request_id
|
|
21
|
+
attr_reader :started_at, :completed_at
|
|
22
|
+
|
|
23
|
+
def initialize(value:, error:, results:, request_id:, started_at:, completed_at:)
|
|
24
|
+
@value = value
|
|
25
|
+
@error = error
|
|
26
|
+
@results = results.freeze
|
|
27
|
+
@request_id = request_id
|
|
28
|
+
@started_at = started_at
|
|
29
|
+
@completed_at = completed_at
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def successful?
|
|
33
|
+
@error.nil?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def failed?
|
|
37
|
+
!successful?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def call_count
|
|
41
|
+
@results.size
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def total_cost
|
|
45
|
+
@results.sum { |r| r.total_cost || 0 }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def input_cost
|
|
49
|
+
@results.sum { |r| r.input_cost || 0 }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def output_cost
|
|
53
|
+
@results.sum { |r| r.output_cost || 0 }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def total_tokens
|
|
57
|
+
@results.sum { |r| r.total_tokens }
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def input_tokens
|
|
61
|
+
@results.sum { |r| r.input_tokens || 0 }
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def output_tokens
|
|
65
|
+
@results.sum { |r| r.output_tokens || 0 }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def duration_ms
|
|
69
|
+
return nil unless @started_at && @completed_at
|
|
70
|
+
((@completed_at - @started_at) * 1000).to_i
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def all_successful?
|
|
74
|
+
@results.all?(&:success?)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def any_errors?
|
|
78
|
+
@results.any?(&:error?)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def errors
|
|
82
|
+
@results.select(&:error?)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def successful
|
|
86
|
+
@results.select(&:success?)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def models_used
|
|
90
|
+
@results.filter_map(&:chosen_model_id).uniq
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def cost_breakdown
|
|
94
|
+
@results.map do |r|
|
|
95
|
+
{
|
|
96
|
+
agent: r.respond_to?(:agent_class_name) ? r.agent_class_name : nil,
|
|
97
|
+
model: r.chosen_model_id,
|
|
98
|
+
cost: r.total_cost || 0,
|
|
99
|
+
tokens: r.total_tokens,
|
|
100
|
+
duration_ms: r.duration_ms
|
|
101
|
+
}
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def to_h
|
|
106
|
+
{
|
|
107
|
+
successful: successful?,
|
|
108
|
+
value: value,
|
|
109
|
+
error: error&.message,
|
|
110
|
+
request_id: request_id,
|
|
111
|
+
call_count: call_count,
|
|
112
|
+
total_cost: total_cost,
|
|
113
|
+
input_cost: input_cost,
|
|
114
|
+
output_cost: output_cost,
|
|
115
|
+
total_tokens: total_tokens,
|
|
116
|
+
input_tokens: input_tokens,
|
|
117
|
+
output_tokens: output_tokens,
|
|
118
|
+
duration_ms: duration_ms,
|
|
119
|
+
started_at: started_at,
|
|
120
|
+
completed_at: completed_at,
|
|
121
|
+
models_used: models_used,
|
|
122
|
+
cost_breakdown: cost_breakdown
|
|
123
|
+
}
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Agents
|
|
5
|
+
# Internal collector used by RubyLLM::Agents.track to accumulate
|
|
6
|
+
# Result objects produced during a tracked block.
|
|
7
|
+
#
|
|
8
|
+
# Not part of the public API — users interact with TrackReport instead.
|
|
9
|
+
#
|
|
10
|
+
# @api private
|
|
11
|
+
class Tracker
|
|
12
|
+
attr_reader :results, :defaults, :request_id, :tags
|
|
13
|
+
|
|
14
|
+
def initialize(defaults: {}, request_id: nil, tags: {})
|
|
15
|
+
@results = []
|
|
16
|
+
@defaults = defaults
|
|
17
|
+
@request_id = request_id || generate_request_id
|
|
18
|
+
@tags = tags
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def <<(result)
|
|
22
|
+
@results << result
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def generate_request_id
|
|
28
|
+
"track_#{SecureRandom.hex(8)}"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
data/lib/ruby_llm/agents.rb
CHANGED
|
@@ -37,7 +37,12 @@ require_relative "agents/infrastructure/budget/config_resolver"
|
|
|
37
37
|
require_relative "agents/infrastructure/budget/forecaster"
|
|
38
38
|
require_relative "agents/infrastructure/budget/spend_recorder"
|
|
39
39
|
|
|
40
|
+
# Tracking
|
|
41
|
+
require_relative "agents/tracker"
|
|
42
|
+
require_relative "agents/track_report"
|
|
43
|
+
|
|
40
44
|
# Results
|
|
45
|
+
require_relative "agents/results/trackable"
|
|
41
46
|
require_relative "agents/results/base"
|
|
42
47
|
require_relative "agents/results/embedding_result"
|
|
43
48
|
require_relative "agents/results/transcription_result"
|
|
@@ -78,6 +83,10 @@ require_relative "agents/image/pipeline"
|
|
|
78
83
|
# Evaluation framework
|
|
79
84
|
require_relative "agents/eval"
|
|
80
85
|
|
|
86
|
+
# Providers (extends RubyLLM with additional providers)
|
|
87
|
+
require_relative "agents/providers/inception"
|
|
88
|
+
RubyLLM::Provider.register :inception, RubyLLM::Agents::Providers::Inception
|
|
89
|
+
|
|
81
90
|
# Rails integration
|
|
82
91
|
if defined?(Rails)
|
|
83
92
|
require_relative "agents/core/inflections"
|
|
@@ -115,6 +124,69 @@ module RubyLLM
|
|
|
115
124
|
# @see RubyLLM::Agents::Configuration
|
|
116
125
|
module Agents
|
|
117
126
|
class << self
|
|
127
|
+
# Wraps a block of agent calls, collecting all Results and
|
|
128
|
+
# returning an aggregated TrackReport.
|
|
129
|
+
#
|
|
130
|
+
# Shared options (tenant, tags, request_id) are injected into
|
|
131
|
+
# every agent instantiated inside the block unless overridden.
|
|
132
|
+
#
|
|
133
|
+
# @param tenant [Hash, Object, nil] Shared tenant for all calls
|
|
134
|
+
# @param request_id [String, nil] Shared request ID (auto-generated if nil)
|
|
135
|
+
# @param tags [Hash] Tags merged into each execution's metadata
|
|
136
|
+
# @param defaults [Hash] Additional shared options for agents
|
|
137
|
+
# @yield Block containing agent calls to track
|
|
138
|
+
# @return [TrackReport] Aggregated report of all calls
|
|
139
|
+
#
|
|
140
|
+
# @example Basic usage
|
|
141
|
+
# report = RubyLLM::Agents.track do
|
|
142
|
+
# ChatAgent.call(query: "hello")
|
|
143
|
+
# SummaryAgent.call(text: "...")
|
|
144
|
+
# end
|
|
145
|
+
# report.total_cost # => 0.015
|
|
146
|
+
#
|
|
147
|
+
# @example With shared tenant
|
|
148
|
+
# report = RubyLLM::Agents.track(tenant: current_user) do
|
|
149
|
+
# AgentA.call(query: "test")
|
|
150
|
+
# end
|
|
151
|
+
def track(tenant: nil, request_id: nil, tags: {}, **defaults)
|
|
152
|
+
defaults[:tenant] = tenant if tenant
|
|
153
|
+
tracker = Tracker.new(defaults: defaults, request_id: request_id, tags: tags)
|
|
154
|
+
|
|
155
|
+
# Stack trackers for nesting support
|
|
156
|
+
previous_tracker = Thread.current[:ruby_llm_agents_tracker]
|
|
157
|
+
Thread.current[:ruby_llm_agents_tracker] = tracker
|
|
158
|
+
|
|
159
|
+
started_at = Time.current
|
|
160
|
+
value = nil
|
|
161
|
+
error = nil
|
|
162
|
+
|
|
163
|
+
begin
|
|
164
|
+
value = yield
|
|
165
|
+
rescue => e
|
|
166
|
+
error = e
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
completed_at = Time.current
|
|
170
|
+
|
|
171
|
+
report = TrackReport.new(
|
|
172
|
+
value: value,
|
|
173
|
+
error: error,
|
|
174
|
+
results: tracker.results,
|
|
175
|
+
request_id: tracker.request_id,
|
|
176
|
+
started_at: started_at,
|
|
177
|
+
completed_at: completed_at
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
# Bubble results up to parent tracker if nested
|
|
181
|
+
if previous_tracker
|
|
182
|
+
tracker.results.each { |r| previous_tracker << r }
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
report
|
|
186
|
+
ensure
|
|
187
|
+
Thread.current[:ruby_llm_agents_tracker] = previous_tracker
|
|
188
|
+
end
|
|
189
|
+
|
|
118
190
|
# Returns the global configuration instance
|
|
119
191
|
#
|
|
120
192
|
# @return [Configuration] The configuration object
|
|
@@ -144,6 +216,146 @@ module RubyLLM
|
|
|
144
216
|
@configuration = Configuration.new
|
|
145
217
|
end
|
|
146
218
|
|
|
219
|
+
# ============================================================
|
|
220
|
+
# Convenience Query API
|
|
221
|
+
# ============================================================
|
|
222
|
+
# These methods provide quick access to execution data without
|
|
223
|
+
# needing to reference model classes directly.
|
|
224
|
+
|
|
225
|
+
# Returns a chainable scope of all executions.
|
|
226
|
+
#
|
|
227
|
+
# @return [ActiveRecord::Relation] All executions
|
|
228
|
+
#
|
|
229
|
+
# @example Recent successful executions
|
|
230
|
+
# RubyLLM::Agents.executions.successful.recent(10)
|
|
231
|
+
#
|
|
232
|
+
# @example Filter by agent
|
|
233
|
+
# RubyLLM::Agents.executions.by_agent("ChatAgent").today
|
|
234
|
+
def executions
|
|
235
|
+
Execution.all
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Returns a usage summary for a given period.
|
|
239
|
+
#
|
|
240
|
+
# @param period [Symbol, Range] :today, :yesterday, :this_week, :this_month,
|
|
241
|
+
# :last_7_days, :last_30_days, or a custom Time range
|
|
242
|
+
# @param agent [String, Class, nil] Optional agent class or name to filter by
|
|
243
|
+
# @param tenant [String, Object, nil] Optional tenant ID or object to filter by
|
|
244
|
+
# @return [Hash] Usage summary with keys:
|
|
245
|
+
# :executions, :successful, :failed, :success_rate,
|
|
246
|
+
# :total_cost, :total_tokens, :avg_duration_ms, :avg_cost
|
|
247
|
+
#
|
|
248
|
+
# @example Global usage today
|
|
249
|
+
# RubyLLM::Agents.usage(period: :today)
|
|
250
|
+
#
|
|
251
|
+
# @example Per-agent usage
|
|
252
|
+
# RubyLLM::Agents.usage(period: :this_month, agent: "ChatAgent")
|
|
253
|
+
#
|
|
254
|
+
# @example Per-tenant usage
|
|
255
|
+
# RubyLLM::Agents.usage(period: :this_week, tenant: current_user)
|
|
256
|
+
def usage(period: :today, agent: nil, tenant: nil)
|
|
257
|
+
scope = scope_for_period(Execution, period)
|
|
258
|
+
scope = scope.by_agent(agent_name_for(agent)) if agent
|
|
259
|
+
scope = scope_for_tenant(scope, tenant) if tenant
|
|
260
|
+
|
|
261
|
+
total = scope.count
|
|
262
|
+
successful = scope.successful.count
|
|
263
|
+
|
|
264
|
+
{
|
|
265
|
+
executions: total,
|
|
266
|
+
successful: successful,
|
|
267
|
+
failed: scope.failed.count,
|
|
268
|
+
success_rate: total.zero? ? 0.0 : (successful.to_f / total * 100).round(1),
|
|
269
|
+
total_cost: scope.sum(:total_cost),
|
|
270
|
+
total_tokens: scope.sum(:total_tokens),
|
|
271
|
+
avg_duration_ms: scope.average(:duration_ms)&.round,
|
|
272
|
+
avg_cost: total.zero? ? 0 : (scope.sum(:total_cost).to_f / total).round(6)
|
|
273
|
+
}
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# Returns cost breakdown by agent for a period.
|
|
277
|
+
#
|
|
278
|
+
# @param period [Symbol, Range] Time period (see #usage)
|
|
279
|
+
# @param tenant [String, Object, nil] Optional tenant filter
|
|
280
|
+
# @return [Hash{String => Hash}] Agent name => { cost:, count:, avg_cost: }
|
|
281
|
+
#
|
|
282
|
+
# @example
|
|
283
|
+
# RubyLLM::Agents.costs(period: :this_month)
|
|
284
|
+
# # => { "ChatAgent" => { cost: 12.50, count: 1000, avg_cost: 0.0125 } }
|
|
285
|
+
def costs(period: :today, tenant: nil)
|
|
286
|
+
scope = scope_for_period(Execution, period)
|
|
287
|
+
scope = scope_for_tenant(scope, tenant) if tenant
|
|
288
|
+
|
|
289
|
+
scope.group(:agent_type).pluck(
|
|
290
|
+
:agent_type,
|
|
291
|
+
Arel.sql("COUNT(*)"),
|
|
292
|
+
Arel.sql("SUM(total_cost)"),
|
|
293
|
+
Arel.sql("AVG(total_cost)")
|
|
294
|
+
).each_with_object({}) do |(agent, count, total, avg), hash|
|
|
295
|
+
hash[agent] = {
|
|
296
|
+
cost: total&.to_f&.round(6) || 0,
|
|
297
|
+
count: count,
|
|
298
|
+
avg_cost: avg&.to_f&.round(6) || 0
|
|
299
|
+
}
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
# Returns all registered agents with their stats.
|
|
304
|
+
#
|
|
305
|
+
# @return [Array<Hash>] Agent info with name, model, stats, etc.
|
|
306
|
+
#
|
|
307
|
+
# @example
|
|
308
|
+
# RubyLLM::Agents.agents
|
|
309
|
+
# # => [{ name: "ChatAgent", active: true, model: "gpt-4o", ... }]
|
|
310
|
+
def agents
|
|
311
|
+
AgentRegistry.all_with_details
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
# Returns a tenant's usage data.
|
|
315
|
+
#
|
|
316
|
+
# @param tenant [String, Object] Tenant ID or object with llm_tenant_id
|
|
317
|
+
# @return [RubyLLM::Agents::Tenant, nil] The tenant record
|
|
318
|
+
#
|
|
319
|
+
# @example
|
|
320
|
+
# tenant = RubyLLM::Agents.tenant_for(current_user)
|
|
321
|
+
# tenant.cost_today # => 0.42
|
|
322
|
+
# tenant.budget_status # => { enabled: true, enforcement: :soft, ... }
|
|
323
|
+
def tenant_for(tenant)
|
|
324
|
+
Tenant.for(tenant)
|
|
325
|
+
rescue
|
|
326
|
+
nil
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
private
|
|
330
|
+
|
|
331
|
+
def scope_for_period(model, period)
|
|
332
|
+
case period
|
|
333
|
+
when :today then model.today
|
|
334
|
+
when :yesterday then model.yesterday
|
|
335
|
+
when :this_week then model.this_week
|
|
336
|
+
when :this_month then model.this_month
|
|
337
|
+
when :last_7_days then model.last_n_days(7)
|
|
338
|
+
when :last_30_days then model.last_n_days(30)
|
|
339
|
+
when Range then model.where(created_at: period)
|
|
340
|
+
else model.all
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def scope_for_tenant(scope, tenant)
|
|
345
|
+
tenant_id = case tenant
|
|
346
|
+
when String then tenant
|
|
347
|
+
else
|
|
348
|
+
tenant.try(:llm_tenant_id) || tenant.try(:tenant_id) || tenant.try(:id)&.to_s
|
|
349
|
+
end
|
|
350
|
+
scope.by_tenant(tenant_id)
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def agent_name_for(agent)
|
|
354
|
+
agent.is_a?(String) ? agent : agent.name
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
public
|
|
358
|
+
|
|
147
359
|
# Renames an agent in the database, updating execution records and
|
|
148
360
|
# tenant budget configuration keys
|
|
149
361
|
#
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
namespace :ruby_llm_agents do
|
|
4
|
+
desc "Validate your RubyLLM::Agents setup (API keys, migrations, routes, jobs)"
|
|
5
|
+
task doctor: :environment do
|
|
6
|
+
require "generators/ruby_llm_agents/doctor_generator"
|
|
7
|
+
RubyLlmAgents::DoctorGenerator.start([])
|
|
8
|
+
end
|
|
9
|
+
|
|
4
10
|
desc "Rename an agent type in execution records. Usage: rake ruby_llm_agents:rename_agent FROM=OldName TO=NewName [DRY_RUN=1]"
|
|
5
11
|
task rename_agent: :environment do
|
|
6
12
|
from = ENV["FROM"]
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ruby_llm-agents
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- adham90
|
|
@@ -82,6 +82,7 @@ files:
|
|
|
82
82
|
- app/controllers/ruby_llm/agents/agents_controller.rb
|
|
83
83
|
- app/controllers/ruby_llm/agents/dashboard_controller.rb
|
|
84
84
|
- app/controllers/ruby_llm/agents/executions_controller.rb
|
|
85
|
+
- app/controllers/ruby_llm/agents/requests_controller.rb
|
|
85
86
|
- app/controllers/ruby_llm/agents/system_config_controller.rb
|
|
86
87
|
- app/controllers/ruby_llm/agents/tenants_controller.rb
|
|
87
88
|
- app/helpers/ruby_llm/agents/application_helper.rb
|
|
@@ -120,6 +121,8 @@ files:
|
|
|
120
121
|
- app/views/ruby_llm/agents/executions/_list.html.erb
|
|
121
122
|
- app/views/ruby_llm/agents/executions/index.html.erb
|
|
122
123
|
- app/views/ruby_llm/agents/executions/show.html.erb
|
|
124
|
+
- app/views/ruby_llm/agents/requests/index.html.erb
|
|
125
|
+
- app/views/ruby_llm/agents/requests/show.html.erb
|
|
123
126
|
- app/views/ruby_llm/agents/shared/_agent_type_badge.html.erb
|
|
124
127
|
- app/views/ruby_llm/agents/shared/_doc_link.html.erb
|
|
125
128
|
- app/views/ruby_llm/agents/shared/_executions_table.html.erb
|
|
@@ -137,6 +140,8 @@ files:
|
|
|
137
140
|
- config/routes.rb
|
|
138
141
|
- lib/generators/ruby_llm_agents/agent_generator.rb
|
|
139
142
|
- lib/generators/ruby_llm_agents/background_remover_generator.rb
|
|
143
|
+
- lib/generators/ruby_llm_agents/demo_generator.rb
|
|
144
|
+
- lib/generators/ruby_llm_agents/doctor_generator.rb
|
|
140
145
|
- lib/generators/ruby_llm_agents/embedder_generator.rb
|
|
141
146
|
- lib/generators/ruby_llm_agents/image_analyzer_generator.rb
|
|
142
147
|
- lib/generators/ruby_llm_agents/image_editor_generator.rb
|
|
@@ -154,6 +159,7 @@ files:
|
|
|
154
159
|
- lib/generators/ruby_llm_agents/templates/add_assistant_prompt_migration.rb.tt
|
|
155
160
|
- lib/generators/ruby_llm_agents/templates/add_attempts_migration.rb.tt
|
|
156
161
|
- lib/generators/ruby_llm_agents/templates/add_caching_migration.rb.tt
|
|
162
|
+
- lib/generators/ruby_llm_agents/templates/add_dashboard_performance_indexes_migration.rb.tt
|
|
157
163
|
- lib/generators/ruby_llm_agents/templates/add_execution_type_migration.rb.tt
|
|
158
164
|
- lib/generators/ruby_llm_agents/templates/add_finish_reason_migration.rb.tt
|
|
159
165
|
- lib/generators/ruby_llm_agents/templates/add_prompts_migration.rb.tt
|
|
@@ -296,6 +302,12 @@ files:
|
|
|
296
302
|
- lib/ruby_llm/agents/pricing/openrouter_adapter.rb
|
|
297
303
|
- lib/ruby_llm/agents/pricing/portkey_adapter.rb
|
|
298
304
|
- lib/ruby_llm/agents/pricing/ruby_llm_adapter.rb
|
|
305
|
+
- lib/ruby_llm/agents/providers/inception.rb
|
|
306
|
+
- lib/ruby_llm/agents/providers/inception/capabilities.rb
|
|
307
|
+
- lib/ruby_llm/agents/providers/inception/chat.rb
|
|
308
|
+
- lib/ruby_llm/agents/providers/inception/configuration.rb
|
|
309
|
+
- lib/ruby_llm/agents/providers/inception/models.rb
|
|
310
|
+
- lib/ruby_llm/agents/providers/inception/registry.rb
|
|
299
311
|
- lib/ruby_llm/agents/rails/engine.rb
|
|
300
312
|
- lib/ruby_llm/agents/results/background_removal_result.rb
|
|
301
313
|
- lib/ruby_llm/agents/results/base.rb
|
|
@@ -308,11 +320,14 @@ files:
|
|
|
308
320
|
- lib/ruby_llm/agents/results/image_upscale_result.rb
|
|
309
321
|
- lib/ruby_llm/agents/results/image_variation_result.rb
|
|
310
322
|
- lib/ruby_llm/agents/results/speech_result.rb
|
|
323
|
+
- lib/ruby_llm/agents/results/trackable.rb
|
|
311
324
|
- lib/ruby_llm/agents/results/transcription_result.rb
|
|
312
325
|
- lib/ruby_llm/agents/routing.rb
|
|
313
326
|
- lib/ruby_llm/agents/routing/class_methods.rb
|
|
314
327
|
- lib/ruby_llm/agents/routing/result.rb
|
|
315
328
|
- lib/ruby_llm/agents/text/embedder.rb
|
|
329
|
+
- lib/ruby_llm/agents/track_report.rb
|
|
330
|
+
- lib/ruby_llm/agents/tracker.rb
|
|
316
331
|
- lib/tasks/ruby_llm_agents.rake
|
|
317
332
|
homepage: https://github.com/adham90/ruby_llm-agents
|
|
318
333
|
licenses:
|
|
@@ -335,7 +350,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
335
350
|
- !ruby/object:Gem::Version
|
|
336
351
|
version: '0'
|
|
337
352
|
requirements: []
|
|
338
|
-
rubygems_version: 4.0.
|
|
353
|
+
rubygems_version: 4.0.7
|
|
339
354
|
specification_version: 4
|
|
340
355
|
summary: Agent framework for building LLM-powered agents with RubyLLM
|
|
341
356
|
test_files: []
|