ruby_llm-agents 3.0.0 → 3.2.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 +1 -0
- data/app/controllers/ruby_llm/agents/agents_controller.rb +16 -14
- data/app/controllers/ruby_llm/agents/dashboard_controller.rb +20 -20
- data/app/controllers/ruby_llm/agents/executions_controller.rb +5 -7
- data/app/helpers/ruby_llm/agents/application_helper.rb +57 -58
- data/app/models/ruby_llm/agents/execution/analytics.rb +27 -27
- data/app/models/ruby_llm/agents/execution/scopes.rb +4 -6
- data/app/models/ruby_llm/agents/execution.rb +26 -26
- data/app/models/ruby_llm/agents/tenant/budgetable.rb +16 -10
- data/app/models/ruby_llm/agents/tenant/resettable.rb +12 -12
- data/app/models/ruby_llm/agents/tenant/trackable.rb +7 -7
- data/app/services/ruby_llm/agents/agent_registry.rb +6 -6
- data/app/views/layouts/ruby_llm/agents/application.html.erb +142 -11
- data/app/views/ruby_llm/agents/agents/show.html.erb +10 -10
- data/app/views/ruby_llm/agents/dashboard/index.html.erb +10 -10
- data/app/views/ruby_llm/agents/executions/show.html.erb +13 -0
- data/lib/generators/ruby_llm_agents/agent_generator.rb +4 -4
- data/lib/generators/ruby_llm_agents/background_remover_generator.rb +6 -6
- data/lib/generators/ruby_llm_agents/embedder_generator.rb +4 -4
- data/lib/generators/ruby_llm_agents/image_analyzer_generator.rb +7 -7
- data/lib/generators/ruby_llm_agents/image_editor_generator.rb +4 -4
- data/lib/generators/ruby_llm_agents/image_generator_generator.rb +6 -6
- data/lib/generators/ruby_llm_agents/image_pipeline_generator.rb +9 -9
- data/lib/generators/ruby_llm_agents/image_transformer_generator.rb +6 -6
- data/lib/generators/ruby_llm_agents/image_upscaler_generator.rb +4 -4
- data/lib/generators/ruby_llm_agents/image_variator_generator.rb +4 -4
- data/lib/generators/ruby_llm_agents/install_generator.rb +3 -3
- data/lib/generators/ruby_llm_agents/migrate_structure_generator.rb +4 -4
- data/lib/generators/ruby_llm_agents/multi_tenancy_generator.rb +2 -2
- data/lib/generators/ruby_llm_agents/restructure_generator.rb +13 -13
- data/lib/generators/ruby_llm_agents/speaker_generator.rb +6 -6
- data/lib/generators/ruby_llm_agents/templates/add_assistant_prompt_migration.rb.tt +9 -0
- data/lib/generators/ruby_llm_agents/templates/split_execution_details_migration.rb.tt +2 -1
- data/lib/generators/ruby_llm_agents/transcriber_generator.rb +4 -4
- data/lib/generators/ruby_llm_agents/upgrade_generator.rb +22 -3
- data/lib/ruby_llm/agents/audio/speaker.rb +40 -31
- data/lib/ruby_llm/agents/audio/speech_client.rb +328 -0
- data/lib/ruby_llm/agents/audio/speech_pricing.rb +273 -0
- data/lib/ruby_llm/agents/audio/transcriber.rb +33 -33
- data/lib/ruby_llm/agents/base_agent.rb +16 -15
- data/lib/ruby_llm/agents/core/base/callbacks.rb +3 -3
- data/lib/ruby_llm/agents/core/configuration.rb +86 -73
- data/lib/ruby_llm/agents/core/errors.rb +27 -2
- data/lib/ruby_llm/agents/core/instrumentation.rb +101 -65
- data/lib/ruby_llm/agents/core/llm_tenant.rb +7 -7
- data/lib/ruby_llm/agents/core/version.rb +1 -1
- data/lib/ruby_llm/agents/dsl/base.rb +3 -3
- data/lib/ruby_llm/agents/dsl/reliability.rb +9 -9
- data/lib/ruby_llm/agents/image/analyzer/dsl.rb +1 -1
- data/lib/ruby_llm/agents/image/analyzer/execution.rb +4 -4
- data/lib/ruby_llm/agents/image/background_remover/dsl.rb +1 -1
- data/lib/ruby_llm/agents/image/background_remover/execution.rb +3 -3
- data/lib/ruby_llm/agents/image/concerns/image_operation_execution.rb +8 -8
- data/lib/ruby_llm/agents/image/editor/execution.rb +1 -1
- data/lib/ruby_llm/agents/image/generator/pricing.rb +9 -10
- data/lib/ruby_llm/agents/image/generator.rb +6 -6
- data/lib/ruby_llm/agents/image/pipeline/dsl.rb +6 -6
- data/lib/ruby_llm/agents/image/pipeline/execution.rb +9 -9
- data/lib/ruby_llm/agents/image/pipeline.rb +1 -1
- data/lib/ruby_llm/agents/image/transformer/execution.rb +1 -1
- data/lib/ruby_llm/agents/image/upscaler/dsl.rb +1 -1
- data/lib/ruby_llm/agents/image/upscaler/execution.rb +3 -5
- data/lib/ruby_llm/agents/image/variator/execution.rb +1 -1
- data/lib/ruby_llm/agents/infrastructure/alert_manager.rb +4 -4
- data/lib/ruby_llm/agents/infrastructure/attempt_tracker.rb +4 -4
- data/lib/ruby_llm/agents/infrastructure/budget/budget_query.rb +9 -9
- data/lib/ruby_llm/agents/infrastructure/budget/config_resolver.rb +3 -3
- data/lib/ruby_llm/agents/infrastructure/budget/forecaster.rb +1 -1
- data/lib/ruby_llm/agents/infrastructure/budget/spend_recorder.rb +17 -17
- data/lib/ruby_llm/agents/infrastructure/circuit_breaker.rb +1 -0
- data/lib/ruby_llm/agents/infrastructure/execution_logger_job.rb +1 -1
- data/lib/ruby_llm/agents/infrastructure/reliability.rb +6 -6
- data/lib/ruby_llm/agents/pipeline/builder.rb +11 -11
- data/lib/ruby_llm/agents/pipeline/middleware/budget.rb +3 -3
- data/lib/ruby_llm/agents/pipeline/middleware/cache.rb +4 -4
- data/lib/ruby_llm/agents/pipeline/middleware/instrumentation.rb +62 -21
- data/lib/ruby_llm/agents/pipeline/middleware/reliability.rb +2 -3
- data/lib/ruby_llm/agents/pipeline/middleware/tenant.rb +82 -4
- data/lib/ruby_llm/agents/results/background_removal_result.rb +6 -6
- data/lib/ruby_llm/agents/results/embedding_result.rb +15 -15
- data/lib/ruby_llm/agents/results/image_analysis_result.rb +7 -7
- data/lib/ruby_llm/agents/results/image_edit_result.rb +4 -4
- data/lib/ruby_llm/agents/results/image_generation_result.rb +5 -5
- data/lib/ruby_llm/agents/results/image_pipeline_result.rb +4 -4
- data/lib/ruby_llm/agents/results/image_transform_result.rb +4 -4
- data/lib/ruby_llm/agents/results/image_upscale_result.rb +5 -5
- data/lib/ruby_llm/agents/results/image_variation_result.rb +4 -4
- data/lib/ruby_llm/agents/results/transcription_result.rb +1 -1
- data/lib/ruby_llm/agents/text/embedder.rb +13 -13
- metadata +4 -1
|
@@ -166,7 +166,7 @@ module RubyLLM
|
|
|
166
166
|
|
|
167
167
|
def default_transcription_model
|
|
168
168
|
RubyLLM::Agents.configuration.default_transcription_model
|
|
169
|
-
rescue
|
|
169
|
+
rescue
|
|
170
170
|
"whisper-1"
|
|
171
171
|
end
|
|
172
172
|
end
|
|
@@ -334,22 +334,22 @@ module RubyLLM
|
|
|
334
334
|
def agent_cache_key
|
|
335
335
|
# Generate content hash based on input type
|
|
336
336
|
content_hash = case @audio
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
337
|
+
when String
|
|
338
|
+
if @audio.start_with?("http://", "https://")
|
|
339
|
+
Digest::SHA256.hexdigest(@audio)
|
|
340
|
+
elsif File.exist?(@audio)
|
|
341
|
+
Digest::SHA256.file(@audio).hexdigest
|
|
342
|
+
else
|
|
343
|
+
Digest::SHA256.hexdigest(@audio)
|
|
344
|
+
end
|
|
345
|
+
when File, IO
|
|
346
|
+
@audio.rewind if @audio.respond_to?(:rewind)
|
|
347
|
+
Digest::SHA256.hexdigest(@audio.read).tap do
|
|
348
|
+
@audio.rewind if @audio.respond_to?(:rewind)
|
|
349
|
+
end
|
|
350
|
+
else
|
|
351
|
+
Digest::SHA256.hexdigest(@audio.to_s)
|
|
352
|
+
end
|
|
353
353
|
|
|
354
354
|
components = [
|
|
355
355
|
"ruby_llm_agents",
|
|
@@ -389,15 +389,15 @@ module RubyLLM
|
|
|
389
389
|
case audio
|
|
390
390
|
when String
|
|
391
391
|
if audio.start_with?("http://", "https://")
|
|
392
|
-
{
|
|
392
|
+
{source: audio, type: :url}
|
|
393
393
|
elsif looks_like_file_path?(audio)
|
|
394
|
-
{
|
|
394
|
+
{source: audio, type: :file_path}
|
|
395
395
|
else
|
|
396
396
|
# Assume it's binary data
|
|
397
|
-
{
|
|
397
|
+
{source: audio, type: :binary, format: format}
|
|
398
398
|
end
|
|
399
399
|
when File, IO
|
|
400
|
-
{
|
|
400
|
+
{source: audio, type: :file_object}
|
|
401
401
|
else
|
|
402
402
|
raise ArgumentError, "audio must be a file path, URL, File object, or binary data"
|
|
403
403
|
end
|
|
@@ -451,7 +451,7 @@ module RubyLLM
|
|
|
451
451
|
|
|
452
452
|
begin
|
|
453
453
|
return execute_transcription(audio_input, model)
|
|
454
|
-
rescue
|
|
454
|
+
rescue => e
|
|
455
455
|
last_error = e
|
|
456
456
|
retries += 1
|
|
457
457
|
|
|
@@ -498,7 +498,7 @@ module RubyLLM
|
|
|
498
498
|
# @param model [String] Model to use
|
|
499
499
|
# @return [Hash] Options for transcription
|
|
500
500
|
def build_transcribe_options(model)
|
|
501
|
-
options = {
|
|
501
|
+
options = {model: model}
|
|
502
502
|
|
|
503
503
|
# Add language if specified
|
|
504
504
|
lang = resolved_language
|
|
@@ -618,15 +618,15 @@ module RubyLLM
|
|
|
618
618
|
# Estimate based on model and duration
|
|
619
619
|
model = raw_result[:model].to_s
|
|
620
620
|
price_per_minute = case model
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
621
|
+
when /whisper-1/
|
|
622
|
+
0.006
|
|
623
|
+
when /gpt-4o-transcribe/
|
|
624
|
+
0.01
|
|
625
|
+
when /gpt-4o-mini-transcribe/
|
|
626
|
+
0.005
|
|
627
|
+
else
|
|
628
|
+
0.006 # Default to whisper pricing
|
|
629
|
+
end
|
|
630
630
|
|
|
631
631
|
duration_minutes * price_per_minute
|
|
632
632
|
end
|
|
@@ -657,7 +657,7 @@ module RubyLLM
|
|
|
657
657
|
# Calculates exponential backoff delay
|
|
658
658
|
def calculate_backoff(attempt)
|
|
659
659
|
config = self.class.reliability_config
|
|
660
|
-
base = config&.backoff == :constant ? 1.0 : 0.4
|
|
660
|
+
base = (config&.backoff == :constant) ? 1.0 : 0.4
|
|
661
661
|
max_delay = 10.0
|
|
662
662
|
|
|
663
663
|
delay = base * (2**(attempt - 1))
|
|
@@ -133,7 +133,7 @@ module RubyLLM
|
|
|
133
133
|
# @return [void]
|
|
134
134
|
def param(name, required: false, default: nil, type: nil)
|
|
135
135
|
@params ||= {}
|
|
136
|
-
@params[name] = {
|
|
136
|
+
@params[name] = {required: required, default: default, type: type}
|
|
137
137
|
define_method(name) do
|
|
138
138
|
@options[name] || @options[name.to_s] || self.class.params.dig(name, :default)
|
|
139
139
|
end
|
|
@@ -217,7 +217,7 @@ module RubyLLM
|
|
|
217
217
|
|
|
218
218
|
# Fall back to global configuration default
|
|
219
219
|
RubyLLM::Agents.configuration.default_thinking
|
|
220
|
-
rescue
|
|
220
|
+
rescue
|
|
221
221
|
nil
|
|
222
222
|
end
|
|
223
223
|
|
|
@@ -227,13 +227,13 @@ module RubyLLM
|
|
|
227
227
|
|
|
228
228
|
def default_streaming
|
|
229
229
|
RubyLLM::Agents.configuration.default_streaming
|
|
230
|
-
rescue
|
|
230
|
+
rescue
|
|
231
231
|
false
|
|
232
232
|
end
|
|
233
233
|
|
|
234
234
|
def default_temperature
|
|
235
235
|
RubyLLM::Agents.configuration.default_temperature
|
|
236
|
-
rescue
|
|
236
|
+
rescue
|
|
237
237
|
0.7
|
|
238
238
|
end
|
|
239
239
|
end
|
|
@@ -380,7 +380,8 @@ module RubyLLM
|
|
|
380
380
|
base_data.merge(
|
|
381
381
|
model: model,
|
|
382
382
|
system_prompt: system_prompt,
|
|
383
|
-
user_prompt: user_prompt
|
|
383
|
+
user_prompt: user_prompt,
|
|
384
|
+
assistant_prompt: assistant_prompt
|
|
384
385
|
)
|
|
385
386
|
end
|
|
386
387
|
|
|
@@ -454,7 +455,7 @@ module RubyLLM
|
|
|
454
455
|
if tenant_value.is_a?(Hash)
|
|
455
456
|
tenant_value
|
|
456
457
|
elsif tenant_value.respond_to?(:llm_tenant_id)
|
|
457
|
-
{
|
|
458
|
+
{id: tenant_value.llm_tenant_id, object: tenant_value}
|
|
458
459
|
else
|
|
459
460
|
raise ArgumentError, "tenant must be a Hash or respond to :llm_tenant_id"
|
|
460
461
|
end
|
|
@@ -464,7 +465,7 @@ module RubyLLM
|
|
|
464
465
|
#
|
|
465
466
|
# @return [Array<Class>] Tool classes to use
|
|
466
467
|
def resolved_tools
|
|
467
|
-
if self.class.
|
|
468
|
+
if self.class.method_defined?(:tools, false)
|
|
468
469
|
tools
|
|
469
470
|
else
|
|
470
471
|
self.class.tools
|
|
@@ -492,7 +493,7 @@ module RubyLLM
|
|
|
492
493
|
prefill = assistant_prompt
|
|
493
494
|
return nil if prefill.nil? || (prefill.is_a?(String) && prefill.empty?)
|
|
494
495
|
|
|
495
|
-
{
|
|
496
|
+
{role: :assistant, content: prefill}
|
|
496
497
|
end
|
|
497
498
|
|
|
498
499
|
# Returns whether streaming is enabled
|
|
@@ -543,7 +544,7 @@ module RubyLLM
|
|
|
543
544
|
|
|
544
545
|
if config[:type] && has_value && !value.nil? && !value.is_a?(config[:type])
|
|
545
546
|
raise ArgumentError,
|
|
546
|
-
|
|
547
|
+
"#{self.class} expected #{config[:type]} for :#{name}, got #{value.class}"
|
|
547
548
|
end
|
|
548
549
|
end
|
|
549
550
|
end
|
|
@@ -593,8 +594,8 @@ module RubyLLM
|
|
|
593
594
|
def build_client(context = nil)
|
|
594
595
|
effective_model = context&.model || model
|
|
595
596
|
client = RubyLLM.chat
|
|
596
|
-
|
|
597
|
-
|
|
597
|
+
.with_model(effective_model)
|
|
598
|
+
.with_temperature(temperature)
|
|
598
599
|
|
|
599
600
|
client = client.with_instructions(system_prompt) if system_prompt
|
|
600
601
|
client = client.with_schema(schema) if schema
|
|
@@ -734,7 +735,7 @@ module RubyLLM
|
|
|
734
735
|
return nil unless defined?(RubyLLM::Models)
|
|
735
736
|
|
|
736
737
|
RubyLLM::Models.find(model_id)
|
|
737
|
-
rescue
|
|
738
|
+
rescue
|
|
738
739
|
nil
|
|
739
740
|
end
|
|
740
741
|
|
|
@@ -788,7 +789,7 @@ module RubyLLM
|
|
|
788
789
|
# @return [Hash] Hash with thinking data or empty hash
|
|
789
790
|
def safe_extract_thinking_data(response)
|
|
790
791
|
result_thinking_data(response)
|
|
791
|
-
rescue
|
|
792
|
+
rescue
|
|
792
793
|
{}
|
|
793
794
|
end
|
|
794
795
|
|
|
@@ -893,7 +894,7 @@ module RubyLLM
|
|
|
893
894
|
content = result.to_s
|
|
894
895
|
end
|
|
895
896
|
|
|
896
|
-
{
|
|
897
|
+
{content: content, status: status, error_message: error_message}
|
|
897
898
|
end
|
|
898
899
|
|
|
899
900
|
# Truncates tool result if it exceeds the configured max length
|
|
@@ -916,7 +917,7 @@ module RubyLLM
|
|
|
916
917
|
# @return [Integer] Max length
|
|
917
918
|
def tool_result_max_length
|
|
918
919
|
RubyLLM::Agents.configuration.tool_result_max_length || 10_000
|
|
919
|
-
rescue
|
|
920
|
+
rescue
|
|
920
921
|
10_000
|
|
921
922
|
end
|
|
922
923
|
|
|
@@ -49,7 +49,7 @@ module RubyLLM
|
|
|
49
49
|
# before_call { |context| context.params[:sanitized] = true }
|
|
50
50
|
#
|
|
51
51
|
def before_call(method_name = nil, &block)
|
|
52
|
-
@callbacks ||= {
|
|
52
|
+
@callbacks ||= {before: [], after: []}
|
|
53
53
|
@callbacks[:before] << (block || method_name)
|
|
54
54
|
end
|
|
55
55
|
|
|
@@ -71,7 +71,7 @@ module RubyLLM
|
|
|
71
71
|
# after_call { |context, response| notify_completion(response) }
|
|
72
72
|
#
|
|
73
73
|
def after_call(method_name = nil, &block)
|
|
74
|
-
@callbacks ||= {
|
|
74
|
+
@callbacks ||= {before: [], after: []}
|
|
75
75
|
@callbacks[:after] << (block || method_name)
|
|
76
76
|
end
|
|
77
77
|
|
|
@@ -112,7 +112,7 @@ module RubyLLM
|
|
|
112
112
|
#
|
|
113
113
|
# @return [Hash] Hash with :before and :after arrays
|
|
114
114
|
def callbacks
|
|
115
|
-
@callbacks ||= {
|
|
115
|
+
@callbacks ||= {before: [], after: []}
|
|
116
116
|
end
|
|
117
117
|
end
|
|
118
118
|
|
|
@@ -390,79 +390,84 @@ module RubyLLM
|
|
|
390
390
|
end
|
|
391
391
|
end
|
|
392
392
|
|
|
393
|
+
# Attributes with custom setters (validation) — only readers here
|
|
394
|
+
attr_reader :default_embedding_dimensions, :default_embedding_batch_size
|
|
395
|
+
|
|
393
396
|
# Attributes without validation (simple accessors)
|
|
394
397
|
attr_accessor :default_model,
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
398
|
+
:async_logging,
|
|
399
|
+
:async_max_concurrency,
|
|
400
|
+
:retention_period,
|
|
401
|
+
:dashboard_parent_controller,
|
|
402
|
+
:basic_auth_username,
|
|
403
|
+
:basic_auth_password,
|
|
404
|
+
:default_fallback_models,
|
|
405
|
+
:default_total_timeout,
|
|
406
|
+
:default_streaming,
|
|
407
|
+
:default_tools,
|
|
408
|
+
:default_thinking,
|
|
409
|
+
:on_alert,
|
|
410
|
+
:persist_prompts,
|
|
411
|
+
:persist_responses,
|
|
412
|
+
:multi_tenancy_enabled,
|
|
413
|
+
:persist_messages_summary,
|
|
414
|
+
:default_retryable_patterns,
|
|
415
|
+
:default_embedding_model,
|
|
416
|
+
:track_embeddings,
|
|
417
|
+
:default_transcription_model,
|
|
418
|
+
:track_transcriptions,
|
|
419
|
+
:default_tts_provider,
|
|
420
|
+
:default_tts_model,
|
|
421
|
+
:default_tts_voice,
|
|
422
|
+
:track_speech,
|
|
423
|
+
:elevenlabs_api_key,
|
|
424
|
+
:elevenlabs_api_base,
|
|
425
|
+
:tts_model_pricing,
|
|
426
|
+
:default_tts_cost,
|
|
427
|
+
:track_executions,
|
|
428
|
+
:track_audio,
|
|
429
|
+
:track_cache_hits,
|
|
430
|
+
:default_image_model,
|
|
431
|
+
:default_image_size,
|
|
432
|
+
:default_image_quality,
|
|
433
|
+
:default_image_style,
|
|
434
|
+
:max_image_prompt_length,
|
|
435
|
+
:track_image_generation,
|
|
436
|
+
:image_model_aliases,
|
|
437
|
+
:litellm_pricing_url,
|
|
438
|
+
:litellm_pricing_cache_ttl,
|
|
439
|
+
:default_image_cost,
|
|
440
|
+
:image_model_pricing,
|
|
441
|
+
:default_variator_model,
|
|
442
|
+
:default_editor_model,
|
|
443
|
+
:default_transformer_model,
|
|
444
|
+
:default_upscaler_model,
|
|
445
|
+
:default_variation_strength,
|
|
446
|
+
:default_transform_strength,
|
|
447
|
+
:default_analyzer_model,
|
|
448
|
+
:default_analysis_type,
|
|
449
|
+
:default_analyzer_max_tags,
|
|
450
|
+
:default_background_remover_model,
|
|
451
|
+
:default_background_output_format,
|
|
452
|
+
:root_directory,
|
|
453
|
+
:root_namespace,
|
|
454
|
+
:tool_result_max_length,
|
|
455
|
+
:redaction
|
|
451
456
|
|
|
452
457
|
# Attributes with validation (readers only, custom setters below)
|
|
453
458
|
attr_reader :default_temperature,
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
459
|
+
:default_timeout,
|
|
460
|
+
:anomaly_cost_threshold,
|
|
461
|
+
:anomaly_duration_threshold,
|
|
462
|
+
:per_page,
|
|
463
|
+
:recent_executions_limit,
|
|
464
|
+
:job_retry_attempts,
|
|
465
|
+
:messages_summary_max_length,
|
|
466
|
+
:dashboard_auth,
|
|
467
|
+
:tenant_resolver,
|
|
468
|
+
:tenant_config_resolver,
|
|
469
|
+
:default_retries,
|
|
470
|
+
:budgets
|
|
466
471
|
|
|
467
472
|
attr_writer :cache_store
|
|
468
473
|
|
|
@@ -597,7 +602,7 @@ module RubyLLM
|
|
|
597
602
|
# @param value [Integer, nil] Dimensions (must be nil or > 0)
|
|
598
603
|
# @raise [ArgumentError] If value is not nil or positive
|
|
599
604
|
def default_embedding_dimensions=(value)
|
|
600
|
-
|
|
605
|
+
if !value.nil? && !(value.is_a?(Numeric) && value > 0)
|
|
601
606
|
raise ArgumentError, "default_embedding_dimensions must be nil or greater than 0"
|
|
602
607
|
end
|
|
603
608
|
|
|
@@ -627,13 +632,13 @@ module RubyLLM
|
|
|
627
632
|
@job_retry_attempts = 3
|
|
628
633
|
|
|
629
634
|
# Reliability defaults (all disabled by default for backward compatibility)
|
|
630
|
-
@default_retries = {
|
|
635
|
+
@default_retries = {max: 0, backoff: :exponential, base: 0.4, max_delay: 3.0, on: []}
|
|
631
636
|
@default_fallback_models = []
|
|
632
637
|
@default_total_timeout = nil
|
|
633
638
|
@default_retryable_patterns = {
|
|
634
639
|
rate_limiting: ["rate limit", "rate_limit", "too many requests", "429", "quota"],
|
|
635
640
|
server_errors: ["500", "502", "503", "504", "service unavailable",
|
|
636
|
-
|
|
641
|
+
"internal server error", "bad gateway", "gateway timeout"],
|
|
637
642
|
capacity: ["overloaded", "capacity"]
|
|
638
643
|
}
|
|
639
644
|
|
|
@@ -650,7 +655,7 @@ module RubyLLM
|
|
|
650
655
|
|
|
651
656
|
# Multi-tenancy defaults (disabled for backward compatibility)
|
|
652
657
|
@multi_tenancy_enabled = false
|
|
653
|
-
@tenant_resolver = -> {
|
|
658
|
+
@tenant_resolver = -> {}
|
|
654
659
|
@tenant_config_resolver = nil
|
|
655
660
|
|
|
656
661
|
# Messages summary defaults
|
|
@@ -673,6 +678,14 @@ module RubyLLM
|
|
|
673
678
|
@default_tts_voice = "nova"
|
|
674
679
|
@track_speech = true
|
|
675
680
|
|
|
681
|
+
# ElevenLabs defaults
|
|
682
|
+
@elevenlabs_api_key = nil
|
|
683
|
+
@elevenlabs_api_base = "https://api.elevenlabs.io"
|
|
684
|
+
|
|
685
|
+
# TTS pricing defaults
|
|
686
|
+
@tts_model_pricing = {}
|
|
687
|
+
@default_tts_cost = 0.015
|
|
688
|
+
|
|
676
689
|
# Execution/conversation agent tracking
|
|
677
690
|
@track_executions = true
|
|
678
691
|
@track_audio = true
|
|
@@ -783,7 +796,7 @@ module RubyLLM
|
|
|
783
796
|
return false unless async_available?
|
|
784
797
|
|
|
785
798
|
defined?(::Async::Task) && ::Async::Task.current?
|
|
786
|
-
rescue
|
|
799
|
+
rescue
|
|
787
800
|
false
|
|
788
801
|
end
|
|
789
802
|
|
|
@@ -29,7 +29,7 @@ module RubyLLM
|
|
|
29
29
|
|
|
30
30
|
def initialize(message = nil, model: nil)
|
|
31
31
|
@model = model
|
|
32
|
-
super(message || "Circuit breaker is open#{
|
|
32
|
+
super(message || "Circuit breaker is open#{" for #{model}" if model}")
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
@@ -78,7 +78,7 @@ module RubyLLM
|
|
|
78
78
|
def initialize(message = nil, tenant_id: nil, budget_type: nil)
|
|
79
79
|
@tenant_id = tenant_id
|
|
80
80
|
@budget_type = budget_type
|
|
81
|
-
super(message || "Budget exceeded#{
|
|
81
|
+
super(message || "Budget exceeded#{" for tenant #{tenant_id}" if tenant_id}")
|
|
82
82
|
end
|
|
83
83
|
end
|
|
84
84
|
|
|
@@ -88,5 +88,30 @@ module RubyLLM
|
|
|
88
88
|
|
|
89
89
|
# Raised for configuration issues
|
|
90
90
|
class ConfigurationError < Error; end
|
|
91
|
+
|
|
92
|
+
# ============================================================
|
|
93
|
+
# Speech/Audio Errors
|
|
94
|
+
# ============================================================
|
|
95
|
+
|
|
96
|
+
# Raised when a TTS provider is not supported
|
|
97
|
+
class UnsupportedProviderError < Error
|
|
98
|
+
attr_reader :provider
|
|
99
|
+
|
|
100
|
+
def initialize(message = nil, provider: nil)
|
|
101
|
+
@provider = provider
|
|
102
|
+
super(message || "Provider :#{provider} is not supported for this operation")
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Raised when the TTS API returns an error response
|
|
107
|
+
class SpeechApiError < Error
|
|
108
|
+
attr_reader :status, :response_body
|
|
109
|
+
|
|
110
|
+
def initialize(message = nil, status: nil, response_body: nil)
|
|
111
|
+
@status = status
|
|
112
|
+
@response_body = response_body
|
|
113
|
+
super(message || "Speech API error (status: #{status})")
|
|
114
|
+
end
|
|
115
|
+
end
|
|
91
116
|
end
|
|
92
117
|
end
|