ruby_llm-agents 0.1.0 → 0.2.1

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.
@@ -1,63 +1,63 @@
1
1
  <% if executions.empty? %>
2
- <p class="text-gray-500 text-center py-8">No executions found.</p>
2
+ <p class="text-gray-500 dark:text-gray-400 text-center py-8">No executions found.</p>
3
3
  <% else %>
4
4
  <div class="overflow-x-auto">
5
- <table class="min-w-full divide-y divide-gray-200">
5
+ <table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
6
6
  <thead>
7
7
  <tr>
8
- <th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
9
- <th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Version</th>
10
- <th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Model</th>
11
- <th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Temp</th>
12
- <th scope="col" class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Tokens</th>
13
- <th scope="col" class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Cost</th>
14
- <th scope="col" class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Duration</th>
15
- <th scope="col" class="px-4 py-3 text-right text-xs font-medium text-gray-500 uppercase tracking-wider">Time</th>
8
+ <th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Status</th>
9
+ <th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Version</th>
10
+ <th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Model</th>
11
+ <th scope="col" class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Temp</th>
12
+ <th scope="col" class="px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Tokens</th>
13
+ <th scope="col" class="px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Cost</th>
14
+ <th scope="col" class="px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Duration</th>
15
+ <th scope="col" class="px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Time</th>
16
16
  </tr>
17
17
  </thead>
18
- <tbody class="bg-white divide-y divide-gray-100">
18
+ <tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-100 dark:divide-gray-700">
19
19
  <% executions.each do |execution| %>
20
20
  <!-- Main Row (clickable to expand) -->
21
- <tr class="hover:bg-gray-50 transition-colors cursor-pointer group"
21
+ <tr class="hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors cursor-pointer group"
22
22
  onclick="toggleExecutionDetails('<%= execution.id %>')"
23
23
  id="execution-row-<%= execution.id %>">
24
24
  <td class="px-4 py-3 whitespace-nowrap">
25
25
  <div class="flex items-center">
26
- <svg class="w-4 h-4 mr-2 text-gray-400 transform transition-transform duration-200"
26
+ <svg class="w-4 h-4 mr-2 text-gray-400 dark:text-gray-500 transform transition-transform duration-200"
27
27
  id="chevron-<%= execution.id %>" fill="none" stroke="currentColor" viewBox="0 0 24 24">
28
28
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"/>
29
29
  </svg>
30
30
  <%= render "rubyllm/agents/shared/status_badge", status: execution.status %>
31
31
  </div>
32
32
  </td>
33
- <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
33
+ <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
34
34
  v<%= execution.agent_version %>
35
35
  </td>
36
- <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
36
+ <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
37
37
  <%= execution.model_id %>
38
38
  </td>
39
- <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
39
+ <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
40
40
  <%= execution.temperature %>
41
41
  </td>
42
- <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-900 text-right font-medium">
42
+ <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100 text-right font-medium">
43
43
  <%= number_to_human_short(execution.total_tokens || 0) %>
44
44
  </td>
45
- <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-900 text-right font-medium">
45
+ <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100 text-right font-medium">
46
46
  <%= number_to_human_short(execution.total_cost || 0, prefix: "$", precision: 2) %>
47
47
  </td>
48
- <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-900 text-right font-medium">
48
+ <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100 text-right font-medium">
49
49
  <%= number_with_delimiter(execution.duration_ms || 0) %>ms
50
50
  </td>
51
- <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500 text-right">
51
+ <td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-right">
52
52
  <%= time_ago_in_words(execution.created_at) %> ago
53
53
  </td>
54
54
  </tr>
55
55
 
56
56
  <!-- Error Row (if applicable) -->
57
57
  <% if execution.status_error? && execution.error_message.present? %>
58
- <tr class="bg-red-50">
58
+ <tr class="bg-red-50 dark:bg-red-900/30">
59
59
  <td colspan="8" class="px-4 py-2">
60
- <p class="text-xs text-red-600">
60
+ <p class="text-xs text-red-600 dark:text-red-400">
61
61
  <span class="font-medium"><%= execution.error_class %>:</span>
62
62
  <%= truncate(execution.error_message, length: 150) %>
63
63
  </p>
@@ -66,48 +66,48 @@
66
66
  <% end %>
67
67
 
68
68
  <!-- Expandable Details Row (hidden by default) -->
69
- <tr id="execution-details-<%= execution.id %>" class="hidden bg-gray-50">
69
+ <tr id="execution-details-<%= execution.id %>" class="hidden bg-gray-50 dark:bg-gray-900">
70
70
  <td colspan="8" class="px-4 py-4">
71
71
  <div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
72
72
  <% if execution.respond_to?(:system_prompt) && execution.system_prompt.present? %>
73
73
  <div>
74
- <h4 class="text-xs font-medium text-gray-500 uppercase mb-2">System Prompt</h4>
75
- <pre class="bg-white border border-gray-200 rounded-lg p-3 text-xs overflow-x-auto max-h-48 overflow-y-auto font-mono whitespace-pre-wrap"><%= execution.system_prompt %></pre>
74
+ <h4 class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase mb-2">System Prompt</h4>
75
+ <pre class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-3 text-xs text-gray-900 dark:text-gray-100 overflow-x-auto max-h-48 overflow-y-auto font-mono whitespace-pre-wrap"><%= execution.system_prompt %></pre>
76
76
  </div>
77
77
  <% end %>
78
78
 
79
79
  <% if execution.respond_to?(:user_prompt) && execution.user_prompt.present? %>
80
80
  <div>
81
- <h4 class="text-xs font-medium text-gray-500 uppercase mb-2">User Prompt</h4>
82
- <pre class="bg-white border border-gray-200 rounded-lg p-3 text-xs overflow-x-auto max-h-48 overflow-y-auto font-mono whitespace-pre-wrap"><%= execution.user_prompt %></pre>
81
+ <h4 class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase mb-2">User Prompt</h4>
82
+ <pre class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-3 text-xs text-gray-900 dark:text-gray-100 overflow-x-auto max-h-48 overflow-y-auto font-mono whitespace-pre-wrap"><%= execution.user_prompt %></pre>
83
83
  </div>
84
84
  <% end %>
85
85
 
86
86
  <% if execution.parameters.present? && execution.parameters.any? %>
87
87
  <div>
88
- <h4 class="text-xs font-medium text-gray-500 uppercase mb-2">Parameters</h4>
89
- <pre class="bg-white border border-gray-200 rounded-lg p-3 text-xs overflow-x-auto max-h-48 overflow-y-auto font-mono"><%= JSON.pretty_generate(execution.parameters) %></pre>
88
+ <h4 class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase mb-2">Parameters</h4>
89
+ <pre class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-3 text-xs text-gray-900 dark:text-gray-100 overflow-x-auto max-h-48 overflow-y-auto font-mono"><%= JSON.pretty_generate(execution.parameters) %></pre>
90
90
  </div>
91
91
  <% end %>
92
92
 
93
93
  <% if execution.response.present? && execution.response.any? %>
94
94
  <div>
95
- <h4 class="text-xs font-medium text-gray-500 uppercase mb-2">Response</h4>
96
- <pre class="bg-white border border-gray-200 rounded-lg p-3 text-xs overflow-x-auto max-h-48 overflow-y-auto font-mono"><%= JSON.pretty_generate(execution.response) %></pre>
95
+ <h4 class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase mb-2">Response</h4>
96
+ <pre class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-3 text-xs text-gray-900 dark:text-gray-100 overflow-x-auto max-h-48 overflow-y-auto font-mono"><%= JSON.pretty_generate(execution.response) %></pre>
97
97
  </div>
98
98
  <% end %>
99
99
 
100
100
  <% if execution.metadata.present? && execution.metadata.any? %>
101
101
  <div>
102
- <h4 class="text-xs font-medium text-gray-500 uppercase mb-2">Metadata</h4>
103
- <pre class="bg-white border border-gray-200 rounded-lg p-3 text-xs overflow-x-auto max-h-48 overflow-y-auto font-mono"><%= JSON.pretty_generate(execution.metadata) %></pre>
102
+ <h4 class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase mb-2">Metadata</h4>
103
+ <pre class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg p-3 text-xs text-gray-900 dark:text-gray-100 overflow-x-auto max-h-48 overflow-y-auto font-mono"><%= JSON.pretty_generate(execution.metadata) %></pre>
104
104
  </div>
105
105
  <% end %>
106
106
  </div>
107
107
 
108
108
  <!-- View Full Details Link -->
109
- <div class="mt-3 pt-3 border-t border-gray-200">
110
- <%= link_to ruby_llm_agents.execution_path(execution), class: "text-sm text-blue-600 hover:underline", onclick: "event.stopPropagation();" do %>
109
+ <div class="mt-3 pt-3 border-t border-gray-200 dark:border-gray-700">
110
+ <%= link_to ruby_llm_agents.execution_path(execution), class: "text-sm text-blue-600 dark:text-blue-400 hover:underline", onclick: "event.stopPropagation();" do %>
111
111
  View Full Details &rarr;
112
112
  <% end %>
113
113
  </div>
@@ -128,15 +128,15 @@
128
128
  from_record = ((current_page - 1) * per_page) + 1
129
129
  to_record = [current_page * per_page, total_count].min
130
130
  %>
131
- <div class="mt-4 flex items-center justify-between border-t border-gray-100 pt-4">
132
- <p class="text-sm text-gray-500">
131
+ <div class="mt-4 flex items-center justify-between border-t border-gray-100 dark:border-gray-700 pt-4">
132
+ <p class="text-sm text-gray-500 dark:text-gray-400">
133
133
  Showing <%= from_record %>-<%= to_record %> of <%= number_with_delimiter(total_count) %> executions
134
134
  </p>
135
135
  <nav class="flex items-center space-x-1">
136
136
  <% if current_page > 1 %>
137
- <%= link_to "Previous", url_for(request.query_parameters.merge(page: current_page - 1)), data: { turbo_frame: "executions_table" }, class: "px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50" %>
137
+ <%= link_to "Previous", url_for(request.query_parameters.merge(page: current_page - 1)), data: { turbo_frame: "executions_table" }, class: "px-3 py-1.5 text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700" %>
138
138
  <% else %>
139
- <span class="px-3 py-1.5 text-sm font-medium text-gray-400 bg-gray-100 border border-gray-200 rounded-md cursor-not-allowed">Previous</span>
139
+ <span class="px-3 py-1.5 text-sm font-medium text-gray-400 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md cursor-not-allowed">Previous</span>
140
140
  <% end %>
141
141
 
142
142
  <%
@@ -159,18 +159,18 @@
159
159
 
160
160
  <% pages_to_show.each do |page| %>
161
161
  <% if page == :gap %>
162
- <span class="px-2 py-1.5 text-sm text-gray-500">...</span>
162
+ <span class="px-2 py-1.5 text-sm text-gray-500 dark:text-gray-400">...</span>
163
163
  <% elsif page == current_page %>
164
164
  <span class="px-3 py-1.5 text-sm font-medium text-white bg-blue-600 border border-blue-600 rounded-md"><%= page %></span>
165
165
  <% else %>
166
- <%= link_to page, url_for(request.query_parameters.merge(page: page)), data: { turbo_frame: "executions_table" }, class: "px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50" %>
166
+ <%= link_to page, url_for(request.query_parameters.merge(page: page)), data: { turbo_frame: "executions_table" }, class: "px-3 py-1.5 text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700" %>
167
167
  <% end %>
168
168
  <% end %>
169
169
 
170
170
  <% if current_page < total_pages %>
171
- <%= link_to "Next", url_for(request.query_parameters.merge(page: current_page + 1)), data: { turbo_frame: "executions_table" }, class: "px-3 py-1.5 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50" %>
171
+ <%= link_to "Next", url_for(request.query_parameters.merge(page: current_page + 1)), data: { turbo_frame: "executions_table" }, class: "px-3 py-1.5 text-sm font-medium text-gray-700 dark:text-gray-200 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-md hover:bg-gray-50 dark:hover:bg-gray-700" %>
172
172
  <% else %>
173
- <span class="px-3 py-1.5 text-sm font-medium text-gray-400 bg-gray-100 border border-gray-200 rounded-md cursor-not-allowed">Next</span>
173
+ <span class="px-3 py-1.5 text-sm font-medium text-gray-400 dark:text-gray-500 bg-gray-100 dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md cursor-not-allowed">Next</span>
174
174
  <% end %>
175
175
  </nav>
176
176
  </div>
@@ -1,14 +1,14 @@
1
- <div class="bg-white border border-gray-200 rounded-xl p-4">
1
+ <div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-4">
2
2
  <div class="flex items-center justify-between">
3
- <p class="text-xs text-gray-500 uppercase tracking-wide font-medium"><%= title %></p>
4
- <span class="<%= local_assigns[:icon_color] || 'text-gray-400' %>">
3
+ <p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide font-medium"><%= title %></p>
4
+ <span class="<%= local_assigns[:icon_color] || 'text-gray-400 dark:text-gray-500' %>">
5
5
  <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
6
6
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="<%= icon %>"/>
7
7
  </svg>
8
8
  </span>
9
9
  </div>
10
- <p class="text-xl font-semibold <%= local_assigns[:value_color] || 'text-gray-900' %> mt-2"><%= value %></p>
10
+ <p class="text-xl font-semibold <%= local_assigns[:value_color] || 'text-gray-900 dark:text-gray-100' %> mt-2"><%= value %></p>
11
11
  <% if local_assigns[:subtitle].present? %>
12
- <p class="text-xs text-gray-400"><%= subtitle %></p>
12
+ <p class="text-xs text-gray-400 dark:text-gray-500"><%= subtitle %></p>
13
13
  <% end %>
14
14
  </div>
@@ -8,40 +8,40 @@
8
8
  config = case status.to_s
9
9
  when "running"
10
10
  {
11
- bg: "bg-blue-50",
12
- text: "text-blue-700",
11
+ bg: "bg-blue-50 dark:bg-blue-900/50",
12
+ text: "text-blue-700 dark:text-blue-300",
13
13
  dot: "bg-blue-500",
14
14
  icon: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15",
15
15
  animate: true
16
16
  }
17
17
  when "success"
18
18
  {
19
- bg: "bg-green-50",
20
- text: "text-green-700",
19
+ bg: "bg-green-50 dark:bg-green-900/50",
20
+ text: "text-green-700 dark:text-green-300",
21
21
  dot: "bg-green-500",
22
22
  icon: "M5 13l4 4L19 7",
23
23
  animate: false
24
24
  }
25
25
  when "error"
26
26
  {
27
- bg: "bg-red-50",
28
- text: "text-red-700",
27
+ bg: "bg-red-50 dark:bg-red-900/50",
28
+ text: "text-red-700 dark:text-red-300",
29
29
  dot: "bg-red-500",
30
30
  icon: "M6 18L18 6M6 6l12 12",
31
31
  animate: false
32
32
  }
33
33
  when "timeout"
34
34
  {
35
- bg: "bg-yellow-50",
36
- text: "text-yellow-700",
35
+ bg: "bg-yellow-50 dark:bg-yellow-900/50",
36
+ text: "text-yellow-700 dark:text-yellow-300",
37
37
  dot: "bg-yellow-500",
38
38
  icon: "M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z",
39
39
  animate: false
40
40
  }
41
41
  else
42
42
  {
43
- bg: "bg-gray-50",
44
- text: "text-gray-700",
43
+ bg: "bg-gray-50 dark:bg-gray-700",
44
+ text: "text-gray-700 dark:text-gray-300",
45
45
  dot: "bg-gray-500",
46
46
  icon: "M8.228 9c.549-1.165 2.03-2 3.772-2 2.21 0 4 1.343 4 3 0 1.4-1.278 2.575-3.006 2.907-.542.104-.994.54-.994 1.093m0 3h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z",
47
47
  animate: false
@@ -115,8 +115,8 @@ module RubyLLM
115
115
  update_data.merge!(
116
116
  input_tokens: response.input_tokens,
117
117
  output_tokens: response.output_tokens,
118
- cached_tokens: response.cached_tokens || 0,
119
- cache_creation_tokens: response.cache_creation_tokens || 0,
118
+ cached_tokens: response&.cached_tokens || 0,
119
+ cache_creation_tokens: response&.cache_creation_tokens || 0,
120
120
  model_id: response.model_id || model,
121
121
  response: serialize_response(response)
122
122
  )
@@ -162,8 +162,8 @@ module RubyLLM
162
162
  execution_data.merge!(
163
163
  input_tokens: response.input_tokens,
164
164
  output_tokens: response.output_tokens,
165
- cached_tokens: response.cached_tokens || 0,
166
- cache_creation_tokens: response.cache_creation_tokens || 0,
165
+ cached_tokens: response&.cached_tokens || 0,
166
+ cache_creation_tokens: response&.cache_creation_tokens || 0,
167
167
  model_id: response.model_id || model,
168
168
  response: serialize_response(response)
169
169
  )
@@ -215,8 +215,8 @@ module RubyLLM
215
215
  model_id: response.model_id,
216
216
  input_tokens: response.input_tokens,
217
217
  output_tokens: response.output_tokens,
218
- cached_tokens: response.cached_tokens,
219
- cache_creation_tokens: response.cache_creation_tokens
218
+ cached_tokens: response&.cached_tokens || 0,
219
+ cache_creation_tokens: response&.cache_creation_tokens || 0
220
220
  }.compact
221
221
  end
222
222
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module RubyLLM
4
4
  module Agents
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.1"
6
6
  end
7
7
  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.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - adham90