ruby_llm-agents 0.4.0 → 0.5.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 +46 -13
- data/app/controllers/ruby_llm/agents/api_configurations_controller.rb +214 -0
- data/app/controllers/ruby_llm/agents/{settings_controller.rb → system_config_controller.rb} +3 -3
- data/app/controllers/ruby_llm/agents/tenants_controller.rb +109 -0
- data/app/models/ruby_llm/agents/api_configuration.rb +386 -0
- data/app/models/ruby_llm/agents/tenant_budget.rb +62 -7
- data/app/views/layouts/ruby_llm/agents/application.html.erb +3 -1
- data/app/views/ruby_llm/agents/api_configurations/_api_key_field.html.erb +34 -0
- data/app/views/ruby_llm/agents/api_configurations/_form.html.erb +288 -0
- data/app/views/ruby_llm/agents/api_configurations/edit.html.erb +95 -0
- data/app/views/ruby_llm/agents/api_configurations/edit_tenant.html.erb +97 -0
- data/app/views/ruby_llm/agents/api_configurations/show.html.erb +211 -0
- data/app/views/ruby_llm/agents/api_configurations/tenant.html.erb +179 -0
- data/app/views/ruby_llm/agents/dashboard/_action_center.html.erb +1 -1
- data/app/views/ruby_llm/agents/executions/show.html.erb +82 -0
- data/app/views/ruby_llm/agents/{settings → system_config}/show.html.erb +1 -1
- data/app/views/ruby_llm/agents/tenants/_form.html.erb +150 -0
- data/app/views/ruby_llm/agents/tenants/edit.html.erb +13 -0
- data/app/views/ruby_llm/agents/tenants/index.html.erb +129 -0
- data/app/views/ruby_llm/agents/tenants/show.html.erb +374 -0
- data/config/routes.rb +12 -1
- data/lib/generators/ruby_llm_agents/api_configuration_generator.rb +100 -0
- data/lib/generators/ruby_llm_agents/templates/create_api_configurations_migration.rb.tt +90 -0
- data/lib/ruby_llm/agents/base/execution.rb +83 -0
- data/lib/ruby_llm/agents/base.rb +1 -0
- data/lib/ruby_llm/agents/budget_tracker.rb +285 -23
- data/lib/ruby_llm/agents/configuration.rb +38 -1
- data/lib/ruby_llm/agents/engine.rb +1 -0
- data/lib/ruby_llm/agents/instrumentation.rb +71 -3
- data/lib/ruby_llm/agents/resolved_config.rb +348 -0
- data/lib/ruby_llm/agents/version.rb +1 -1
- metadata +19 -3
|
@@ -245,7 +245,9 @@ module RubyLLM
|
|
|
245
245
|
metadata: metadata,
|
|
246
246
|
system_prompt: config.persist_prompts ? redacted_system_prompt : nil,
|
|
247
247
|
user_prompt: config.persist_prompts ? redacted_user_prompt : nil,
|
|
248
|
-
streaming: self.class.streaming
|
|
248
|
+
streaming: self.class.streaming,
|
|
249
|
+
messages_count: resolved_messages.size,
|
|
250
|
+
messages_summary: config.persist_messages_summary ? messages_summary : {}
|
|
249
251
|
}
|
|
250
252
|
|
|
251
253
|
# Extract tracing fields from metadata if present
|
|
@@ -326,6 +328,9 @@ module RubyLLM
|
|
|
326
328
|
Rails.logger.warn("[RubyLLM::Agents] Cost calculation failed: #{cost_error.message}")
|
|
327
329
|
end
|
|
328
330
|
end
|
|
331
|
+
|
|
332
|
+
# Record token usage for budget tracking
|
|
333
|
+
record_token_usage(execution)
|
|
329
334
|
rescue ActiveRecord::RecordInvalid => e
|
|
330
335
|
Rails.logger.error("[RubyLLM::Agents] Validation failed for execution #{execution&.id}: #{e.record.errors.full_messages.join(', ')}")
|
|
331
336
|
if Rails.env.development? || Rails.env.test?
|
|
@@ -415,6 +420,9 @@ module RubyLLM
|
|
|
415
420
|
Rails.logger.warn("[RubyLLM::Agents] Cost calculation failed: #{cost_error.message}")
|
|
416
421
|
end
|
|
417
422
|
end
|
|
423
|
+
|
|
424
|
+
# Record token usage for budget tracking
|
|
425
|
+
record_token_usage(execution)
|
|
418
426
|
rescue ActiveRecord::RecordInvalid => e
|
|
419
427
|
Rails.logger.error("[RubyLLM::Agents] Validation failed for execution #{execution&.id}: #{e.record.errors.full_messages.join(', ')}")
|
|
420
428
|
if Rails.env.development? || Rails.env.test?
|
|
@@ -440,6 +448,8 @@ module RubyLLM
|
|
|
440
448
|
# @param error [Exception, nil] The exception if failed
|
|
441
449
|
# @return [void]
|
|
442
450
|
def legacy_log_execution(completed_at:, status:, response: nil, error: nil)
|
|
451
|
+
config = RubyLLM::Agents.configuration
|
|
452
|
+
|
|
443
453
|
execution_data = {
|
|
444
454
|
agent_type: self.class.name,
|
|
445
455
|
agent_version: self.class.version,
|
|
@@ -452,7 +462,9 @@ module RubyLLM
|
|
|
452
462
|
parameters: sanitized_parameters,
|
|
453
463
|
metadata: execution_metadata,
|
|
454
464
|
system_prompt: safe_system_prompt,
|
|
455
|
-
user_prompt: safe_user_prompt
|
|
465
|
+
user_prompt: safe_user_prompt,
|
|
466
|
+
messages_count: resolved_messages.size,
|
|
467
|
+
messages_summary: config.persist_messages_summary ? messages_summary : {}
|
|
456
468
|
}
|
|
457
469
|
|
|
458
470
|
# Add response data if available (using safe extraction)
|
|
@@ -516,6 +528,38 @@ module RubyLLM
|
|
|
516
528
|
Redactor.redact_string(prompt)
|
|
517
529
|
end
|
|
518
530
|
|
|
531
|
+
# Returns a summary of messages (first and last, truncated)
|
|
532
|
+
#
|
|
533
|
+
# Creates a summary of the conversation messages containing the first
|
|
534
|
+
# and last messages (if different) with content truncated for storage.
|
|
535
|
+
#
|
|
536
|
+
# @return [Hash] Summary with :first and :last message hashes, or empty hash
|
|
537
|
+
def messages_summary
|
|
538
|
+
msgs = resolved_messages
|
|
539
|
+
return {} if msgs.blank?
|
|
540
|
+
|
|
541
|
+
max_len = RubyLLM::Agents.configuration.messages_summary_max_length || 500
|
|
542
|
+
|
|
543
|
+
summary = {}
|
|
544
|
+
|
|
545
|
+
if msgs.first
|
|
546
|
+
summary[:first] = {
|
|
547
|
+
role: msgs.first[:role].to_s,
|
|
548
|
+
content: Redactor.redact_string(msgs.first[:content].to_s).truncate(max_len)
|
|
549
|
+
}
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
# Only add last if there are multiple messages and last is different from first
|
|
553
|
+
if msgs.size > 1 && msgs.last
|
|
554
|
+
summary[:last] = {
|
|
555
|
+
role: msgs.last[:role].to_s,
|
|
556
|
+
content: Redactor.redact_string(msgs.last[:content].to_s).truncate(max_len)
|
|
557
|
+
}
|
|
558
|
+
end
|
|
559
|
+
|
|
560
|
+
summary
|
|
561
|
+
end
|
|
562
|
+
|
|
519
563
|
# Returns the response with redaction applied
|
|
520
564
|
#
|
|
521
565
|
# @param response [RubyLLM::Message] The LLM response
|
|
@@ -773,7 +817,9 @@ module RubyLLM
|
|
|
773
817
|
total_cost: 0,
|
|
774
818
|
parameters: redacted_parameters,
|
|
775
819
|
metadata: execution_metadata,
|
|
776
|
-
streaming: self.class.streaming
|
|
820
|
+
streaming: self.class.streaming,
|
|
821
|
+
messages_count: resolved_messages.size,
|
|
822
|
+
messages_summary: config.persist_messages_summary ? messages_summary : {}
|
|
777
823
|
}
|
|
778
824
|
|
|
779
825
|
# Add tracing fields from metadata if present
|
|
@@ -798,6 +844,28 @@ module RubyLLM
|
|
|
798
844
|
Rails.logger.error("[RubyLLM::Agents] Failed to record cache hit execution: #{e.message}")
|
|
799
845
|
end
|
|
800
846
|
|
|
847
|
+
# Records token usage to the BudgetTracker
|
|
848
|
+
#
|
|
849
|
+
# @param execution [Execution] The completed execution record
|
|
850
|
+
# @return [void]
|
|
851
|
+
def record_token_usage(execution)
|
|
852
|
+
return unless execution&.total_tokens && execution.total_tokens > 0
|
|
853
|
+
|
|
854
|
+
begin
|
|
855
|
+
tenant_id = respond_to?(:resolved_tenant_id) ? resolved_tenant_id : nil
|
|
856
|
+
tenant_config = respond_to?(:runtime_tenant_config) ? runtime_tenant_config : nil
|
|
857
|
+
|
|
858
|
+
BudgetTracker.record_tokens!(
|
|
859
|
+
self.class.name,
|
|
860
|
+
execution.total_tokens,
|
|
861
|
+
tenant_id: tenant_id,
|
|
862
|
+
tenant_config: tenant_config
|
|
863
|
+
)
|
|
864
|
+
rescue StandardError => e
|
|
865
|
+
Rails.logger.warn("[RubyLLM::Agents] Failed to record token usage: #{e.message}")
|
|
866
|
+
end
|
|
867
|
+
end
|
|
868
|
+
|
|
801
869
|
# Emergency fallback to mark execution as failed
|
|
802
870
|
#
|
|
803
871
|
# Uses update_all to bypass ActiveRecord callbacks and validations,
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RubyLLM
|
|
4
|
+
module Agents
|
|
5
|
+
# Resolves API configuration with priority chain
|
|
6
|
+
#
|
|
7
|
+
# Resolution order:
|
|
8
|
+
# 1. Tenant-specific database config (if tenant_id provided)
|
|
9
|
+
# 2. Global database config
|
|
10
|
+
# 3. RubyLLM.configuration (set via initializer or environment)
|
|
11
|
+
#
|
|
12
|
+
# This class provides a unified interface for accessing configuration
|
|
13
|
+
# values regardless of their source, and can apply the resolved
|
|
14
|
+
# configuration to RubyLLM.
|
|
15
|
+
#
|
|
16
|
+
# @example Basic resolution
|
|
17
|
+
# resolved = ResolvedConfig.new(
|
|
18
|
+
# tenant_config: ApiConfiguration.for_tenant("acme"),
|
|
19
|
+
# global_config: ApiConfiguration.global,
|
|
20
|
+
# ruby_llm_config: RubyLLM.configuration
|
|
21
|
+
# )
|
|
22
|
+
#
|
|
23
|
+
# resolved.openai_api_key # => Returns from highest priority source
|
|
24
|
+
# resolved.source_for(:openai_api_key) # => "tenant:acme"
|
|
25
|
+
#
|
|
26
|
+
# @example Applying to RubyLLM
|
|
27
|
+
# resolved.apply_to_ruby_llm! # Applies all resolved values
|
|
28
|
+
#
|
|
29
|
+
# @see ApiConfiguration
|
|
30
|
+
# @api public
|
|
31
|
+
class ResolvedConfig
|
|
32
|
+
# Returns all resolvable attributes (API keys + settings)
|
|
33
|
+
# Lazy-loaded to avoid circular dependency with ApiConfiguration
|
|
34
|
+
#
|
|
35
|
+
# @return [Array<Symbol>]
|
|
36
|
+
def self.resolvable_attributes
|
|
37
|
+
@resolvable_attributes ||= (
|
|
38
|
+
ApiConfiguration::API_KEY_ATTRIBUTES +
|
|
39
|
+
ApiConfiguration::NON_KEY_ATTRIBUTES
|
|
40
|
+
).freeze
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# @return [ApiConfiguration, nil] Tenant-specific configuration
|
|
44
|
+
attr_reader :tenant_config
|
|
45
|
+
|
|
46
|
+
# @return [ApiConfiguration, nil] Global database configuration
|
|
47
|
+
attr_reader :global_config
|
|
48
|
+
|
|
49
|
+
# @return [Object] RubyLLM configuration object
|
|
50
|
+
attr_reader :ruby_llm_config
|
|
51
|
+
|
|
52
|
+
# Creates a new resolved configuration
|
|
53
|
+
#
|
|
54
|
+
# @param tenant_config [ApiConfiguration, nil] Tenant-specific config
|
|
55
|
+
# @param global_config [ApiConfiguration, nil] Global database config
|
|
56
|
+
# @param ruby_llm_config [Object] RubyLLM.configuration
|
|
57
|
+
def initialize(tenant_config:, global_config:, ruby_llm_config:)
|
|
58
|
+
@tenant_config = tenant_config
|
|
59
|
+
@global_config = global_config
|
|
60
|
+
@ruby_llm_config = ruby_llm_config
|
|
61
|
+
@resolved_cache = {}
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Resolves a specific attribute value using the priority chain
|
|
65
|
+
#
|
|
66
|
+
# @param attr_name [Symbol, String] The attribute name
|
|
67
|
+
# @return [Object, nil] The resolved value
|
|
68
|
+
def resolve(attr_name)
|
|
69
|
+
attr_sym = attr_name.to_sym
|
|
70
|
+
return @resolved_cache[attr_sym] if @resolved_cache.key?(attr_sym)
|
|
71
|
+
|
|
72
|
+
@resolved_cache[attr_sym] = resolve_attribute(attr_sym)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Returns the source of a resolved attribute value
|
|
76
|
+
#
|
|
77
|
+
# @param attr_name [Symbol, String] The attribute name
|
|
78
|
+
# @return [String] Source label: "tenant:ID", "global_db", "ruby_llm_config", or "not_set"
|
|
79
|
+
def source_for(attr_name)
|
|
80
|
+
attr_sym = attr_name.to_sym
|
|
81
|
+
|
|
82
|
+
# Check tenant config first (if present and inherits or has value)
|
|
83
|
+
if tenant_config&.has_value?(attr_sym)
|
|
84
|
+
return "tenant:#{tenant_config.scope_id}"
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Check global DB config (only if tenant inherits or no tenant)
|
|
88
|
+
if should_check_global?(attr_sym) && global_config&.has_value?(attr_sym)
|
|
89
|
+
return "global_db"
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Check RubyLLM config
|
|
93
|
+
if ruby_llm_value_present?(attr_sym)
|
|
94
|
+
return "ruby_llm_config"
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
"not_set"
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Returns all resolved values as a hash
|
|
101
|
+
#
|
|
102
|
+
# @return [Hash] All resolved configuration values
|
|
103
|
+
def to_hash
|
|
104
|
+
self.class.resolvable_attributes.each_with_object({}) do |attr, hash|
|
|
105
|
+
value = resolve(attr)
|
|
106
|
+
hash[attr] = value if value.present?
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# Returns a hash suitable for RubyLLM configuration
|
|
111
|
+
#
|
|
112
|
+
# Only includes values that differ from or override the current
|
|
113
|
+
# RubyLLM configuration.
|
|
114
|
+
#
|
|
115
|
+
# @return [Hash] Configuration hash for RubyLLM
|
|
116
|
+
def to_ruby_llm_options
|
|
117
|
+
to_hash.slice(*ruby_llm_configurable_attributes)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Applies the resolved configuration to RubyLLM
|
|
121
|
+
#
|
|
122
|
+
# This temporarily overrides RubyLLM.configuration with the
|
|
123
|
+
# resolved values. Useful for per-request configuration.
|
|
124
|
+
#
|
|
125
|
+
# @return [void]
|
|
126
|
+
def apply_to_ruby_llm!
|
|
127
|
+
options = to_ruby_llm_options
|
|
128
|
+
return if options.empty?
|
|
129
|
+
|
|
130
|
+
RubyLLM.configure do |config|
|
|
131
|
+
options.each do |key, value|
|
|
132
|
+
setter = "#{key}="
|
|
133
|
+
config.public_send(setter, value) if config.respond_to?(setter)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# Dynamic accessor for resolvable attributes
|
|
139
|
+
# Uses method_missing to provide accessors without eager loading constants
|
|
140
|
+
#
|
|
141
|
+
# @param method_name [Symbol] The method being called
|
|
142
|
+
# @param args [Array] Method arguments
|
|
143
|
+
# @return [Object] The resolved value for the attribute
|
|
144
|
+
def method_missing(method_name, *args)
|
|
145
|
+
if self.class.resolvable_attributes.include?(method_name)
|
|
146
|
+
resolve(method_name)
|
|
147
|
+
else
|
|
148
|
+
super
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Indicates which dynamic methods are supported
|
|
153
|
+
#
|
|
154
|
+
# @param method_name [Symbol] The method name to check
|
|
155
|
+
# @param include_private [Boolean] Whether to include private methods
|
|
156
|
+
# @return [Boolean] True if the method is a resolvable attribute
|
|
157
|
+
def respond_to_missing?(method_name, include_private = false)
|
|
158
|
+
self.class.resolvable_attributes.include?(method_name) || super
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Returns provider status with source information
|
|
162
|
+
#
|
|
163
|
+
# @return [Array<Hash>] Provider status with source info
|
|
164
|
+
def provider_statuses_with_source
|
|
165
|
+
ApiConfiguration::PROVIDERS.map do |key, info|
|
|
166
|
+
key_attr = info[:key_attr]
|
|
167
|
+
value = resolve(key_attr)
|
|
168
|
+
|
|
169
|
+
{
|
|
170
|
+
key: key,
|
|
171
|
+
name: info[:name],
|
|
172
|
+
configured: value.present?,
|
|
173
|
+
masked_key: value.present? ? mask_string(value) : nil,
|
|
174
|
+
source: source_for(key_attr),
|
|
175
|
+
capabilities: info[:capabilities]
|
|
176
|
+
}
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Checks if any database configuration exists
|
|
181
|
+
#
|
|
182
|
+
# @return [Boolean]
|
|
183
|
+
def has_db_config?
|
|
184
|
+
tenant_config.present? || global_config.present?
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# Returns summary of configuration sources
|
|
188
|
+
#
|
|
189
|
+
# @return [Hash] Summary with counts per source
|
|
190
|
+
def source_summary
|
|
191
|
+
summary = Hash.new(0)
|
|
192
|
+
|
|
193
|
+
self.class.resolvable_attributes.each do |attr|
|
|
194
|
+
source = source_for(attr)
|
|
195
|
+
summary[source] += 1 if resolve(attr).present?
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
summary
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Public method to get raw RubyLLM config value for an attribute
|
|
202
|
+
# This returns the value from RubyLLM.configuration (initializer/ENV)
|
|
203
|
+
# regardless of any database overrides.
|
|
204
|
+
#
|
|
205
|
+
# @param attr_name [Symbol, String] The attribute name
|
|
206
|
+
# @return [Object, nil] The RubyLLM config value
|
|
207
|
+
def ruby_llm_value_for(attr_name)
|
|
208
|
+
ruby_llm_value(attr_name.to_sym)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
# Masks a string for display (public wrapper)
|
|
212
|
+
#
|
|
213
|
+
# @param value [String] The string to mask
|
|
214
|
+
# @return [String] Masked string
|
|
215
|
+
def mask_string(value)
|
|
216
|
+
return nil if value.blank?
|
|
217
|
+
return "****" if value.length <= 8
|
|
218
|
+
|
|
219
|
+
"#{value[0..1]}****#{value[-4..]}"
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
private
|
|
223
|
+
|
|
224
|
+
# Resolves a single attribute using the priority chain
|
|
225
|
+
#
|
|
226
|
+
# @param attr_sym [Symbol] The attribute name
|
|
227
|
+
# @return [Object, nil] The resolved value
|
|
228
|
+
def resolve_attribute(attr_sym)
|
|
229
|
+
# 1. Check tenant config
|
|
230
|
+
if tenant_config&.has_value?(attr_sym)
|
|
231
|
+
return tenant_config.send(attr_sym)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# 2. Check global DB config (if tenant allows inheritance or no tenant)
|
|
235
|
+
if should_check_global?(attr_sym)
|
|
236
|
+
if global_config&.has_value?(attr_sym)
|
|
237
|
+
return global_config.send(attr_sym)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
# 3. Fall back to RubyLLM config
|
|
242
|
+
ruby_llm_value(attr_sym)
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Determines if we should check global config
|
|
246
|
+
#
|
|
247
|
+
# @param attr_sym [Symbol] The attribute name
|
|
248
|
+
# @return [Boolean]
|
|
249
|
+
def should_check_global?(attr_sym)
|
|
250
|
+
return true unless tenant_config
|
|
251
|
+
|
|
252
|
+
# If tenant has inherit_global_defaults enabled, check global
|
|
253
|
+
tenant_config.inherit_global_defaults != false
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# Gets a value from RubyLLM configuration
|
|
257
|
+
#
|
|
258
|
+
# @param attr_sym [Symbol] The attribute name
|
|
259
|
+
# @return [Object, nil]
|
|
260
|
+
def ruby_llm_value(attr_sym)
|
|
261
|
+
return nil unless ruby_llm_config
|
|
262
|
+
|
|
263
|
+
# Map our attribute names to RubyLLM config method names
|
|
264
|
+
method_name = ruby_llm_config_mapping(attr_sym)
|
|
265
|
+
return nil unless method_name
|
|
266
|
+
|
|
267
|
+
if ruby_llm_config.respond_to?(method_name)
|
|
268
|
+
ruby_llm_config.send(method_name)
|
|
269
|
+
end
|
|
270
|
+
rescue StandardError
|
|
271
|
+
nil
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Checks if a RubyLLM config value is present
|
|
275
|
+
#
|
|
276
|
+
# @param attr_sym [Symbol] The attribute name
|
|
277
|
+
# @return [Boolean]
|
|
278
|
+
def ruby_llm_value_present?(attr_sym)
|
|
279
|
+
value = ruby_llm_value(attr_sym)
|
|
280
|
+
value.present?
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
# Maps our attribute names to RubyLLM configuration method names
|
|
284
|
+
#
|
|
285
|
+
# @param attr_sym [Symbol] Our attribute name
|
|
286
|
+
# @return [Symbol, nil] RubyLLM config method name
|
|
287
|
+
def ruby_llm_config_mapping(attr_sym)
|
|
288
|
+
# Most attributes map directly
|
|
289
|
+
mapping = {
|
|
290
|
+
openai_api_key: :openai_api_key,
|
|
291
|
+
anthropic_api_key: :anthropic_api_key,
|
|
292
|
+
gemini_api_key: :gemini_api_key,
|
|
293
|
+
deepseek_api_key: :deepseek_api_key,
|
|
294
|
+
mistral_api_key: :mistral_api_key,
|
|
295
|
+
perplexity_api_key: :perplexity_api_key,
|
|
296
|
+
openrouter_api_key: :openrouter_api_key,
|
|
297
|
+
gpustack_api_key: :gpustack_api_key,
|
|
298
|
+
xai_api_key: :xai_api_key,
|
|
299
|
+
ollama_api_key: :ollama_api_key,
|
|
300
|
+
bedrock_api_key: :bedrock_api_key,
|
|
301
|
+
bedrock_secret_key: :bedrock_secret_key,
|
|
302
|
+
bedrock_session_token: :bedrock_session_token,
|
|
303
|
+
bedrock_region: :bedrock_region,
|
|
304
|
+
vertexai_credentials: :vertexai_credentials,
|
|
305
|
+
vertexai_project_id: :vertexai_project_id,
|
|
306
|
+
vertexai_location: :vertexai_location,
|
|
307
|
+
openai_api_base: :openai_api_base,
|
|
308
|
+
gemini_api_base: :gemini_api_base,
|
|
309
|
+
ollama_api_base: :ollama_api_base,
|
|
310
|
+
gpustack_api_base: :gpustack_api_base,
|
|
311
|
+
xai_api_base: :xai_api_base,
|
|
312
|
+
openai_organization_id: :openai_organization_id,
|
|
313
|
+
openai_project_id: :openai_project_id,
|
|
314
|
+
default_model: :default_model,
|
|
315
|
+
default_embedding_model: :default_embedding_model,
|
|
316
|
+
default_image_model: :default_image_model,
|
|
317
|
+
default_moderation_model: :default_moderation_model,
|
|
318
|
+
request_timeout: :request_timeout,
|
|
319
|
+
max_retries: :max_retries,
|
|
320
|
+
retry_interval: :retry_interval,
|
|
321
|
+
retry_backoff_factor: :retry_backoff_factor,
|
|
322
|
+
retry_interval_randomness: :retry_interval_randomness,
|
|
323
|
+
http_proxy: :http_proxy
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
mapping[attr_sym]
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
# Returns attributes that can be set on RubyLLM configuration
|
|
330
|
+
#
|
|
331
|
+
# @return [Array<Symbol>]
|
|
332
|
+
def ruby_llm_configurable_attributes
|
|
333
|
+
ApiConfiguration::API_KEY_ATTRIBUTES +
|
|
334
|
+
ApiConfiguration::ENDPOINT_ATTRIBUTES +
|
|
335
|
+
ApiConfiguration::MODEL_ATTRIBUTES +
|
|
336
|
+
ApiConfiguration::CONNECTION_ATTRIBUTES +
|
|
337
|
+
%i[
|
|
338
|
+
openai_organization_id
|
|
339
|
+
openai_project_id
|
|
340
|
+
bedrock_region
|
|
341
|
+
vertexai_project_id
|
|
342
|
+
vertexai_location
|
|
343
|
+
]
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
end
|
|
347
|
+
end
|
|
348
|
+
end
|
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: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- adham90
|
|
@@ -65,10 +65,13 @@ files:
|
|
|
65
65
|
- app/controllers/concerns/ruby_llm/agents/filterable.rb
|
|
66
66
|
- app/controllers/concerns/ruby_llm/agents/paginatable.rb
|
|
67
67
|
- app/controllers/ruby_llm/agents/agents_controller.rb
|
|
68
|
+
- app/controllers/ruby_llm/agents/api_configurations_controller.rb
|
|
68
69
|
- app/controllers/ruby_llm/agents/dashboard_controller.rb
|
|
69
70
|
- app/controllers/ruby_llm/agents/executions_controller.rb
|
|
70
|
-
- app/controllers/ruby_llm/agents/
|
|
71
|
+
- app/controllers/ruby_llm/agents/system_config_controller.rb
|
|
72
|
+
- app/controllers/ruby_llm/agents/tenants_controller.rb
|
|
71
73
|
- app/helpers/ruby_llm/agents/application_helper.rb
|
|
74
|
+
- app/models/ruby_llm/agents/api_configuration.rb
|
|
72
75
|
- app/models/ruby_llm/agents/execution.rb
|
|
73
76
|
- app/models/ruby_llm/agents/execution/analytics.rb
|
|
74
77
|
- app/models/ruby_llm/agents/execution/metrics.rb
|
|
@@ -83,6 +86,12 @@ files:
|
|
|
83
86
|
- app/views/ruby_llm/agents/agents/_workflow.html.erb
|
|
84
87
|
- app/views/ruby_llm/agents/agents/index.html.erb
|
|
85
88
|
- app/views/ruby_llm/agents/agents/show.html.erb
|
|
89
|
+
- app/views/ruby_llm/agents/api_configurations/_api_key_field.html.erb
|
|
90
|
+
- app/views/ruby_llm/agents/api_configurations/_form.html.erb
|
|
91
|
+
- app/views/ruby_llm/agents/api_configurations/edit.html.erb
|
|
92
|
+
- app/views/ruby_llm/agents/api_configurations/edit_tenant.html.erb
|
|
93
|
+
- app/views/ruby_llm/agents/api_configurations/show.html.erb
|
|
94
|
+
- app/views/ruby_llm/agents/api_configurations/tenant.html.erb
|
|
86
95
|
- app/views/ruby_llm/agents/dashboard/_action_center.html.erb
|
|
87
96
|
- app/views/ruby_llm/agents/dashboard/_agent_comparison.html.erb
|
|
88
97
|
- app/views/ruby_llm/agents/dashboard/_alerts_feed.html.erb
|
|
@@ -100,7 +109,6 @@ files:
|
|
|
100
109
|
- app/views/ruby_llm/agents/executions/dry_run.html.erb
|
|
101
110
|
- app/views/ruby_llm/agents/executions/index.html.erb
|
|
102
111
|
- app/views/ruby_llm/agents/executions/show.html.erb
|
|
103
|
-
- app/views/ruby_llm/agents/settings/show.html.erb
|
|
104
112
|
- app/views/ruby_llm/agents/shared/_breadcrumbs.html.erb
|
|
105
113
|
- app/views/ruby_llm/agents/shared/_executions_table.html.erb
|
|
106
114
|
- app/views/ruby_llm/agents/shared/_filter_dropdown.html.erb
|
|
@@ -111,8 +119,14 @@ files:
|
|
|
111
119
|
- app/views/ruby_llm/agents/shared/_status_dot.html.erb
|
|
112
120
|
- app/views/ruby_llm/agents/shared/_tenant_filter.html.erb
|
|
113
121
|
- app/views/ruby_llm/agents/shared/_workflow_type_badge.html.erb
|
|
122
|
+
- app/views/ruby_llm/agents/system_config/show.html.erb
|
|
123
|
+
- app/views/ruby_llm/agents/tenants/_form.html.erb
|
|
124
|
+
- app/views/ruby_llm/agents/tenants/edit.html.erb
|
|
125
|
+
- app/views/ruby_llm/agents/tenants/index.html.erb
|
|
126
|
+
- app/views/ruby_llm/agents/tenants/show.html.erb
|
|
114
127
|
- config/routes.rb
|
|
115
128
|
- lib/generators/ruby_llm_agents/agent_generator.rb
|
|
129
|
+
- lib/generators/ruby_llm_agents/api_configuration_generator.rb
|
|
116
130
|
- lib/generators/ruby_llm_agents/install_generator.rb
|
|
117
131
|
- lib/generators/ruby_llm_agents/multi_tenancy_generator.rb
|
|
118
132
|
- lib/generators/ruby_llm_agents/templates/add_attempts_migration.rb.tt
|
|
@@ -127,6 +141,7 @@ files:
|
|
|
127
141
|
- lib/generators/ruby_llm_agents/templates/add_workflow_migration.rb.tt
|
|
128
142
|
- lib/generators/ruby_llm_agents/templates/agent.rb.tt
|
|
129
143
|
- lib/generators/ruby_llm_agents/templates/application_agent.rb.tt
|
|
144
|
+
- lib/generators/ruby_llm_agents/templates/create_api_configurations_migration.rb.tt
|
|
130
145
|
- lib/generators/ruby_llm_agents/templates/create_tenant_budgets_migration.rb.tt
|
|
131
146
|
- lib/generators/ruby_llm_agents/templates/initializer.rb.tt
|
|
132
147
|
- lib/generators/ruby_llm_agents/templates/migration.rb.tt
|
|
@@ -160,6 +175,7 @@ files:
|
|
|
160
175
|
- lib/ruby_llm/agents/reliability/executor.rb
|
|
161
176
|
- lib/ruby_llm/agents/reliability/fallback_routing.rb
|
|
162
177
|
- lib/ruby_llm/agents/reliability/retry_strategy.rb
|
|
178
|
+
- lib/ruby_llm/agents/resolved_config.rb
|
|
163
179
|
- lib/ruby_llm/agents/result.rb
|
|
164
180
|
- lib/ruby_llm/agents/version.rb
|
|
165
181
|
- lib/ruby_llm/agents/workflow.rb
|