ruby_llm-agents 1.3.3 → 1.3.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 185514669cc03ca7601f244c9bc0a0db41c58515e0693480fc18d93ef2e2d028
4
- data.tar.gz: f2319cb5e4020219b8f2ca6fc1ceed3fe738696a37c09ed4c98395cd450aabe6
3
+ metadata.gz: b65843b4d3c71ceba5fe61973aaefe40135cbfb4330a2bffe223fe4bd7264635
4
+ data.tar.gz: '069100e15512c507cc0eae7c674cb884a35eea460c20e4dc46fefe572c699850'
5
5
  SHA512:
6
- metadata.gz: 55744523240ada2af5ab892da799eb4c42abedf3b504aff16f9f30b1fbc54ca6f919aae62e115a58005975845e87b716ee3b6b620882d6b1ca973c39ce0a06a1
7
- data.tar.gz: d5ef918e581f8b469dead7fe638bf4cdf14dea177f0e534af4aab62fbbe814295677117030eec72e81433a4025b02f34f6774bc56a6a55c0f5fdc87b0272a10e
6
+ metadata.gz: 8eae2f88345529b8d2a1aa0c7c13bc4507686273eef5011ab4900fa81f50c249ddee25fee71f6483c71c6c68968ae1cc0e42b909a17d5ea923a358a4303de06f
7
+ data.tar.gz: de73b936bc4c71ae428231048be59818e19d77a1b806ab4b5715c5c17cec8be55457a6f16e27d516aadb47b8ad6716f0e48db5340a2217846c182857a010651b
@@ -398,7 +398,27 @@
398
398
  <% end %>
399
399
  </div>
400
400
 
401
+ <% error_attempts = @execution.attempts.select { |a| a['error_class'].present? } %>
402
+ <% if error_attempts.any? %>
403
+ <script type="application/json" id="all-errors-data">
404
+ <%= raw error_attempts.map { |a|
405
+ lines = ["#{a['error_class']}: #{a['error_message']}"]
406
+ lines += (a['error_backtrace'] || [])
407
+ "Model: #{a['model_id']}\n#{lines.join("\n")}"
408
+ }.join("\n\n---\n\n").to_json %>
409
+ </script>
410
+ <% end %>
411
+
401
412
  <div class="overflow-x-auto">
413
+ <% if error_attempts.any? %>
414
+ <div class="flex justify-end mb-2">
415
+ <button onclick="var text = JSON.parse(document.getElementById('all-errors-data').textContent); navigator.clipboard.writeText(text).then(function() { var btn = event.currentTarget; btn.textContent = 'Copied!'; setTimeout(function() { btn.textContent = 'Copy all errors'; }, 2000); });"
416
+ class="inline-flex items-center gap-1.5 px-2.5 py-1 text-xs font-medium text-gray-600 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-md transition-colors">
417
+ <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"/></svg>
418
+ Copy all errors
419
+ </button>
420
+ </div>
421
+ <% end %>
402
422
  <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
403
423
  <thead>
404
424
  <tr>
@@ -455,16 +475,46 @@
455
475
  -
456
476
  <% end %>
457
477
  </td>
458
- <td class="px-3 py-2 text-sm">
478
+ <td class="px-3 py-2 text-sm max-w-xs">
459
479
  <% if attempt['error_class'].present? %>
460
- <span class="text-red-600 dark:text-red-400 font-mono text-xs" title="<%= attempt['error_message'] %>">
461
- <%= attempt['error_class'].split('::').last.truncate(30) %>
462
- </span>
480
+ <div>
481
+ <span class="text-red-600 dark:text-red-400 font-mono text-xs font-medium">
482
+ <%= attempt['error_class'].split('::').last %>
483
+ </span>
484
+ </div>
485
+ <p class="text-red-500 dark:text-red-400 text-xs mt-0.5 break-words">
486
+ <%= attempt['error_message'].to_s.truncate(150) %>
487
+ </p>
488
+ <% if attempt['error_backtrace'].present? %>
489
+ <button onclick="var el = document.getElementById('backtrace-<%= index %>'); el.classList.toggle('hidden');"
490
+ class="text-xs text-gray-500 dark:text-gray-400 hover:text-red-500 dark:hover:text-red-400 mt-1 underline">
491
+ Stack trace
492
+ </button>
493
+ <% end %>
463
494
  <% else %>
464
495
  <span class="text-gray-400">-</span>
465
496
  <% end %>
466
497
  </td>
467
498
  </tr>
499
+ <% if attempt['error_backtrace'].present? %>
500
+ <tr id="backtrace-<%= index %>" class="hidden">
501
+ <td colspan="6" class="px-3 py-2">
502
+ <div class="bg-gray-900 text-gray-100 text-xs font-mono p-3 rounded-lg max-h-64 overflow-auto whitespace-pre-wrap relative group/bt">
503
+ <button onclick="var el = document.getElementById('backtrace-text-<%= index %>'); navigator.clipboard.writeText(el.textContent.trim()).then(function() { var btn = event.currentTarget; btn.querySelector('span').textContent = 'Copied!'; setTimeout(function() { btn.querySelector('span').textContent = 'Copy'; }, 2000); });"
504
+ class="absolute top-2 right-2 inline-flex items-center gap-1 px-2 py-0.5 text-xs text-gray-400 hover:text-white bg-gray-800 hover:bg-gray-700 rounded transition-colors">
505
+ <svg class="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 5H6a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2v-1M8 5a2 2 0 002 2h2a2 2 0 002-2M8 5a2 2 0 012-2h2a2 2 0 012 2m0 0h2a2 2 0 012 2v3m2 4H10m0 0l3-3m-3 3l3 3"/></svg>
506
+ <span>Copy</span>
507
+ </button>
508
+ <div id="backtrace-text-<%= index %>">
509
+ <div class="font-semibold text-red-400 mb-1"><%= attempt['error_class'] %>: <%= attempt['error_message'].to_s.truncate(200) %></div>
510
+ <% attempt['error_backtrace'].each do |line| %>
511
+ <div class="text-gray-300 leading-relaxed"><%= line %></div>
512
+ <% end %>
513
+ </div>
514
+ </div>
515
+ </td>
516
+ </tr>
517
+ <% end %>
468
518
  <% end %>
469
519
  </tbody>
470
520
  </table>
@@ -4,6 +4,6 @@ module RubyLLM
4
4
  module Agents
5
5
  # Current version of the RubyLLM::Agents gem
6
6
  # @return [String] Semantic version string
7
- VERSION = "1.3.3"
7
+ VERSION = "1.3.4"
8
8
  end
9
9
  end
@@ -73,6 +73,7 @@ module RubyLLM
73
73
  if error
74
74
  attempt[:error_class] = error.class.name
75
75
  attempt[:error_message] = error.message.to_s.truncate(1000)
76
+ attempt[:error_backtrace] = error.backtrace&.first(20)
76
77
  end
77
78
 
78
79
  @attempts << attempt
@@ -88,7 +88,7 @@ module RubyLLM
88
88
  #
89
89
  # @api public
90
90
  class AllModelsExhaustedError < Error
91
- attr_reader :models_tried, :last_error, :attempts
91
+ attr_reader :models_tried, :last_error, :attempts, :errors
92
92
 
93
93
  # @param models_tried [Array<String>] List of models that were attempted
94
94
  # @param last_error [Exception] The last error that occurred
@@ -97,7 +97,42 @@ module RubyLLM
97
97
  @models_tried = models_tried
98
98
  @last_error = last_error
99
99
  @attempts = attempts
100
- super("All models exhausted: #{models_tried.join(', ')}. Last error: #{last_error.message}")
100
+ @errors = build_errors
101
+ super(build_message)
102
+ end
103
+
104
+ private
105
+
106
+ def build_errors
107
+ return [] unless @attempts&.any?
108
+
109
+ @attempts.filter_map do |attempt|
110
+ if attempt["short_circuited"]
111
+ { model: attempt["model_id"], error_class: "CircuitBreakerOpen", error_message: "circuit breaker open",
112
+ error_backtrace: nil }
113
+ elsif attempt["error_class"]
114
+ { model: attempt["model_id"], error_class: attempt["error_class"], error_message: attempt["error_message"],
115
+ error_backtrace: attempt["error_backtrace"] }
116
+ end
117
+ end
118
+ end
119
+
120
+ def build_message
121
+ parts = ["All models exhausted:"]
122
+ if @attempts&.any?
123
+ @attempts.each do |attempt|
124
+ model = attempt["model_id"]
125
+ if attempt["short_circuited"]
126
+ parts << " #{model}: circuit breaker open"
127
+ elsif attempt["error_class"]
128
+ parts << " #{model}: #{attempt['error_class']} - #{attempt['error_message']}"
129
+ end
130
+ end
131
+ else
132
+ parts << " Models: #{@models_tried.join(', ')}"
133
+ parts << " Last error: #{@last_error.message}"
134
+ end
135
+ parts.join("\n")
101
136
  end
102
137
  end
103
138
 
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: 1.3.3
4
+ version: 1.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - adham90