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.
- checksums.yaml +4 -4
- data/app/views/layouts/rubyllm/agents/application.html.erb +100 -25
- data/app/views/rubyllm/agents/agents/index.html.erb +19 -19
- data/app/views/rubyllm/agents/agents/show.html.erb +89 -89
- data/app/views/rubyllm/agents/dashboard/_execution_item.html.erb +10 -10
- data/app/views/rubyllm/agents/dashboard/index.html.erb +11 -11
- data/app/views/rubyllm/agents/executions/_filters.html.erb +33 -33
- data/app/views/rubyllm/agents/executions/_list.html.erb +31 -31
- data/app/views/rubyllm/agents/executions/index.html.erb +1 -1
- data/app/views/rubyllm/agents/executions/show.html.erb +40 -40
- data/app/views/rubyllm/agents/shared/_executions_table.html.erb +43 -43
- data/app/views/rubyllm/agents/shared/_stat_card.html.erb +5 -5
- data/app/views/rubyllm/agents/shared/_status_badge.html.erb +10 -10
- data/lib/ruby_llm/agents/instrumentation.rb +6 -6
- data/lib/ruby_llm/agents/version.rb +1 -1
- metadata +1 -1
|
@@ -3,16 +3,16 @@
|
|
|
3
3
|
selected_agents = params[:agent_types].present? ? (params[:agent_types].is_a?(Array) ? params[:agent_types] : params[:agent_types].split(",")) : []
|
|
4
4
|
selected_statuses = params[:statuses].present? ? (params[:statuses].is_a?(Array) ? params[:statuses] : params[:statuses].split(",")) : []
|
|
5
5
|
%>
|
|
6
|
-
<div class="bg-white rounded-xl border border-gray-200 p-4 mb-6">
|
|
6
|
+
<div class="bg-white dark:bg-gray-800 rounded-xl border border-gray-200 dark:border-gray-700 p-4 mb-6" data-controller="filter-dropdown">
|
|
7
7
|
<%= form_with url: ruby_llm_agents.executions_path, method: :get, data: { turbo_frame: "executions_content", turbo_action: "advance" }, id: "filters-form" do |f| %>
|
|
8
8
|
<div class="flex flex-wrap items-center gap-3">
|
|
9
9
|
<!-- Agent Type Filter (Multi-select) -->
|
|
10
10
|
<div class="relative filter-dropdown" data-filter="agent_types">
|
|
11
|
-
<button type="button" onclick="toggleDropdown(this)" class="flex items-center gap-2 px-3 py-2 text-sm bg-gray-50 border border-gray-200 rounded-lg hover:bg-gray-100 transition-colors <%= selected_agents.any? ? 'ring-2 ring-blue-500 ring-offset-1' : '' %>">
|
|
11
|
+
<button type="button" onclick="toggleDropdown(this)" class="flex items-center gap-2 px-3 py-2 text-sm bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-600 transition-colors <%= selected_agents.any? ? 'ring-2 ring-blue-500 ring-offset-1' : '' %>">
|
|
12
12
|
<svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
13
13
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
|
|
14
14
|
</svg>
|
|
15
|
-
<span class="dropdown-label text-gray-700">
|
|
15
|
+
<span class="dropdown-label text-gray-700 dark:text-gray-200">
|
|
16
16
|
<% if selected_agents.empty? %>
|
|
17
17
|
All Agents
|
|
18
18
|
<% elsif selected_agents.length == 1 %>
|
|
@@ -25,16 +25,16 @@
|
|
|
25
25
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
26
26
|
</svg>
|
|
27
27
|
</button>
|
|
28
|
-
<div class="dropdown-menu hidden absolute z-10 mt-1 w-56 bg-white rounded-lg shadow-lg border border-gray-200 py-1">
|
|
29
|
-
<div class="px-3 py-2 border-b border-gray-100">
|
|
28
|
+
<div class="dropdown-menu hidden absolute z-10 mt-1 w-56 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-1">
|
|
29
|
+
<div class="px-3 py-2 border-b border-gray-100 dark:border-gray-700">
|
|
30
30
|
<label class="flex items-center gap-2 cursor-pointer">
|
|
31
|
-
<input type="checkbox" class="select-all-checkbox rounded border-gray-300 text-blue-600 focus:ring-blue-500" onchange="toggleAllOptions(this, 'agent_types')" <%= selected_agents.empty? ? 'checked' : '' %>>
|
|
32
|
-
<span class="text-sm font-medium text-gray-700">All Agents</span>
|
|
31
|
+
<input type="checkbox" class="select-all-checkbox rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500 dark:bg-gray-700" onchange="toggleAllOptions(this, 'agent_types')" <%= selected_agents.empty? ? 'checked' : '' %>>
|
|
32
|
+
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">All Agents</span>
|
|
33
33
|
</label>
|
|
34
34
|
</div>
|
|
35
35
|
<% agent_types.each do |agent_type| %>
|
|
36
|
-
<label class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 cursor-pointer">
|
|
37
|
-
<input type="checkbox" name="agent_types[]" value="<%= agent_type %>" class="filter-checkbox rounded border-gray-300 text-blue-600 focus:ring-blue-500" onchange="updateMultiSelect('agent_types')" <%= selected_agents.include?(agent_type) ? 'checked' : '' %>>
|
|
36
|
+
<label class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer">
|
|
37
|
+
<input type="checkbox" name="agent_types[]" value="<%= agent_type %>" class="filter-checkbox rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500 dark:bg-gray-700" onchange="updateMultiSelect('agent_types')" <%= selected_agents.include?(agent_type) ? 'checked' : '' %>>
|
|
38
38
|
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
39
39
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.75 17L9 20l-1 1h8l-1-1-.75-3M3 13h18M5 17h14a2 2 0 002-2V5a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
|
|
40
40
|
</svg>
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
|
|
47
47
|
<!-- Status Filter (Multi-select) -->
|
|
48
48
|
<div class="relative filter-dropdown" data-filter="statuses">
|
|
49
|
-
<button type="button" onclick="toggleDropdown(this)" class="flex items-center gap-2 px-3 py-2 text-sm bg-gray-50 border border-gray-200 rounded-lg hover:bg-gray-100 transition-colors <%= selected_statuses.any? ? 'ring-2 ring-blue-500 ring-offset-1' : '' %>">
|
|
49
|
+
<button type="button" onclick="toggleDropdown(this)" class="flex items-center gap-2 px-3 py-2 text-sm bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-600 transition-colors <%= selected_statuses.any? ? 'ring-2 ring-blue-500 ring-offset-1' : '' %>">
|
|
50
50
|
<% if selected_statuses.length == 1
|
|
51
51
|
status_color = case selected_statuses.first
|
|
52
52
|
when 'success' then 'bg-green-500'
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
status_color = 'bg-gray-400'
|
|
60
60
|
end %>
|
|
61
61
|
<span class="w-2 h-2 rounded-full <%= status_color %>"></span>
|
|
62
|
-
<span class="dropdown-label text-gray-700">
|
|
62
|
+
<span class="dropdown-label text-gray-700 dark:text-gray-200">
|
|
63
63
|
<% if selected_statuses.empty? %>
|
|
64
64
|
All Statuses
|
|
65
65
|
<% elsif selected_statuses.length == 1 %>
|
|
@@ -72,30 +72,30 @@
|
|
|
72
72
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
73
73
|
</svg>
|
|
74
74
|
</button>
|
|
75
|
-
<div class="dropdown-menu hidden absolute z-10 mt-1 w-44 bg-white rounded-lg shadow-lg border border-gray-200 py-1">
|
|
76
|
-
<div class="px-3 py-2 border-b border-gray-100">
|
|
75
|
+
<div class="dropdown-menu hidden absolute z-10 mt-1 w-44 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-1">
|
|
76
|
+
<div class="px-3 py-2 border-b border-gray-100 dark:border-gray-700">
|
|
77
77
|
<label class="flex items-center gap-2 cursor-pointer">
|
|
78
|
-
<input type="checkbox" class="select-all-checkbox rounded border-gray-300 text-blue-600 focus:ring-blue-500" onchange="toggleAllOptions(this, 'statuses')" <%= selected_statuses.empty? ? 'checked' : '' %>>
|
|
79
|
-
<span class="text-sm font-medium text-gray-700">All Statuses</span>
|
|
78
|
+
<input type="checkbox" class="select-all-checkbox rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500 dark:bg-gray-700" onchange="toggleAllOptions(this, 'statuses')" <%= selected_statuses.empty? ? 'checked' : '' %>>
|
|
79
|
+
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">All Statuses</span>
|
|
80
80
|
</label>
|
|
81
81
|
</div>
|
|
82
|
-
<label class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 cursor-pointer">
|
|
83
|
-
<input type="checkbox" name="statuses[]" value="success" class="filter-checkbox rounded border-gray-300 text-blue-600 focus:ring-blue-500" onchange="updateMultiSelect('statuses')" <%= selected_statuses.include?('success') ? 'checked' : '' %>>
|
|
82
|
+
<label class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer">
|
|
83
|
+
<input type="checkbox" name="statuses[]" value="success" class="filter-checkbox rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500 dark:bg-gray-700" onchange="updateMultiSelect('statuses')" <%= selected_statuses.include?('success') ? 'checked' : '' %>>
|
|
84
84
|
<span class="w-2 h-2 rounded-full bg-green-500"></span>
|
|
85
85
|
Success
|
|
86
86
|
</label>
|
|
87
|
-
<label class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 cursor-pointer">
|
|
88
|
-
<input type="checkbox" name="statuses[]" value="error" class="filter-checkbox rounded border-gray-300 text-blue-600 focus:ring-blue-500" onchange="updateMultiSelect('statuses')" <%= selected_statuses.include?('error') ? 'checked' : '' %>>
|
|
87
|
+
<label class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer">
|
|
88
|
+
<input type="checkbox" name="statuses[]" value="error" class="filter-checkbox rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500 dark:bg-gray-700" onchange="updateMultiSelect('statuses')" <%= selected_statuses.include?('error') ? 'checked' : '' %>>
|
|
89
89
|
<span class="w-2 h-2 rounded-full bg-red-500"></span>
|
|
90
90
|
Error
|
|
91
91
|
</label>
|
|
92
|
-
<label class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 cursor-pointer">
|
|
93
|
-
<input type="checkbox" name="statuses[]" value="running" class="filter-checkbox rounded border-gray-300 text-blue-600 focus:ring-blue-500" onchange="updateMultiSelect('statuses')" <%= selected_statuses.include?('running') ? 'checked' : '' %>>
|
|
92
|
+
<label class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer">
|
|
93
|
+
<input type="checkbox" name="statuses[]" value="running" class="filter-checkbox rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500 dark:bg-gray-700" onchange="updateMultiSelect('statuses')" <%= selected_statuses.include?('running') ? 'checked' : '' %>>
|
|
94
94
|
<span class="w-2 h-2 rounded-full bg-blue-500 animate-pulse"></span>
|
|
95
95
|
Running
|
|
96
96
|
</label>
|
|
97
|
-
<label class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 cursor-pointer">
|
|
98
|
-
<input type="checkbox" name="statuses[]" value="timeout" class="filter-checkbox rounded border-gray-300 text-blue-600 focus:ring-blue-500" onchange="updateMultiSelect('statuses')" <%= selected_statuses.include?('timeout') ? 'checked' : '' %>>
|
|
97
|
+
<label class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 cursor-pointer">
|
|
98
|
+
<input type="checkbox" name="statuses[]" value="timeout" class="filter-checkbox rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500 dark:bg-gray-700" onchange="updateMultiSelect('statuses')" <%= selected_statuses.include?('timeout') ? 'checked' : '' %>>
|
|
99
99
|
<span class="w-2 h-2 rounded-full bg-yellow-500"></span>
|
|
100
100
|
Timeout
|
|
101
101
|
</label>
|
|
@@ -104,11 +104,11 @@
|
|
|
104
104
|
|
|
105
105
|
<!-- Time Range Filter -->
|
|
106
106
|
<div class="relative filter-dropdown" data-filter="days">
|
|
107
|
-
<button type="button" onclick="toggleDropdown(this)" class="flex items-center gap-2 px-3 py-2 text-sm bg-gray-50 border border-gray-200 rounded-lg hover:bg-gray-100 transition-colors <%= params[:days].present? ? 'ring-2 ring-blue-500 ring-offset-1' : '' %>">
|
|
107
|
+
<button type="button" onclick="toggleDropdown(this)" class="flex items-center gap-2 px-3 py-2 text-sm bg-gray-50 dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-600 transition-colors <%= params[:days].present? ? 'ring-2 ring-blue-500 ring-offset-1' : '' %>">
|
|
108
108
|
<svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
109
109
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
|
110
110
|
</svg>
|
|
111
|
-
<span class="dropdown-label text-gray-700">
|
|
111
|
+
<span class="dropdown-label text-gray-700 dark:text-gray-200">
|
|
112
112
|
<% case params[:days]
|
|
113
113
|
when '1' then %>Today<%
|
|
114
114
|
when '7' then %>Last 7 Days<%
|
|
@@ -120,26 +120,26 @@
|
|
|
120
120
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"/>
|
|
121
121
|
</svg>
|
|
122
122
|
</button>
|
|
123
|
-
<div class="dropdown-menu hidden absolute z-10 mt-1 w-40 bg-white rounded-lg shadow-lg border border-gray-200 py-1">
|
|
124
|
-
<a href="#" onclick="selectSingleFilter('days', '', 'All Time'); return false;" class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 <%= params[:days].blank? ? 'bg-blue-50 text-blue-700' : '' %>">
|
|
123
|
+
<div class="dropdown-menu hidden absolute z-10 mt-1 w-40 bg-white dark:bg-gray-800 rounded-lg shadow-lg border border-gray-200 dark:border-gray-700 py-1">
|
|
124
|
+
<a href="#" onclick="selectSingleFilter('days', '', 'All Time'); return false;" class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 <%= params[:days].blank? ? 'bg-blue-50 dark:bg-blue-900/50 text-blue-700 dark:text-blue-300' : '' %>">
|
|
125
125
|
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
126
126
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
|
127
127
|
</svg>
|
|
128
128
|
All Time
|
|
129
129
|
</a>
|
|
130
|
-
<a href="#" onclick="selectSingleFilter('days', '1', 'Today'); return false;" class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 <%= params[:days] == '1' ? 'bg-blue-50 text-blue-700' : '' %>">
|
|
130
|
+
<a href="#" onclick="selectSingleFilter('days', '1', 'Today'); return false;" class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 <%= params[:days] == '1' ? 'bg-blue-50 dark:bg-blue-900/50 text-blue-700 dark:text-blue-300' : '' %>">
|
|
131
131
|
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
132
132
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
133
133
|
</svg>
|
|
134
134
|
Today
|
|
135
135
|
</a>
|
|
136
|
-
<a href="#" onclick="selectSingleFilter('days', '7', 'Last 7 Days'); return false;" class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 <%= params[:days] == '7' ? 'bg-blue-50 text-blue-700' : '' %>">
|
|
136
|
+
<a href="#" onclick="selectSingleFilter('days', '7', 'Last 7 Days'); return false;" class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 <%= params[:days] == '7' ? 'bg-blue-50 dark:bg-blue-900/50 text-blue-700 dark:text-blue-300' : '' %>">
|
|
137
137
|
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
138
138
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
|
139
139
|
</svg>
|
|
140
140
|
Last 7 Days
|
|
141
141
|
</a>
|
|
142
|
-
<a href="#" onclick="selectSingleFilter('days', '30', 'Last 30 Days'); return false;" class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 hover:bg-gray-50 <%= params[:days] == '30' ? 'bg-blue-50 text-blue-700' : '' %>">
|
|
142
|
+
<a href="#" onclick="selectSingleFilter('days', '30', 'Last 30 Days'); return false;" class="flex items-center gap-2 px-3 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-50 dark:hover:bg-gray-700 <%= params[:days] == '30' ? 'bg-blue-50 dark:bg-blue-900/50 text-blue-700 dark:text-blue-300' : '' %>">
|
|
143
143
|
<svg class="w-4 h-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
144
144
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"/>
|
|
145
145
|
</svg>
|
|
@@ -160,11 +160,11 @@
|
|
|
160
160
|
<% end %>
|
|
161
161
|
|
|
162
162
|
<!-- Stats Summary (right aligned) -->
|
|
163
|
-
<div class="ml-auto flex items-center gap-4 text-sm text-gray-500">
|
|
163
|
+
<div class="ml-auto flex items-center gap-4 text-sm text-gray-500 dark:text-gray-400">
|
|
164
164
|
<span><%= number_to_human_short(filter_stats[:total_count]) %> executions</span>
|
|
165
|
-
<span class="text-gray-300">|</span>
|
|
165
|
+
<span class="text-gray-300 dark:text-gray-600">|</span>
|
|
166
166
|
<span><%= number_to_human_short(filter_stats[:total_cost], prefix: "$", precision: 2) %></span>
|
|
167
|
-
<span class="text-gray-300">|</span>
|
|
167
|
+
<span class="text-gray-300 dark:text-gray-600">|</span>
|
|
168
168
|
<span><%= number_to_human_short(filter_stats[:total_tokens]) %> tokens</span>
|
|
169
169
|
</div>
|
|
170
170
|
</div>
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
<div class="bg-white rounded-lg shadow overflow-hidden">
|
|
1
|
+
<div class="bg-white dark:bg-gray-800 rounded-lg shadow overflow-hidden">
|
|
2
2
|
<% if executions.empty? %>
|
|
3
|
-
<div class="px-6 py-12 text-center text-gray-500">
|
|
3
|
+
<div class="px-6 py-12 text-center text-gray-500 dark:text-gray-400">
|
|
4
4
|
<p class="text-lg">No executions found</p>
|
|
5
5
|
<p class="text-sm mt-1">Try adjusting your filters</p>
|
|
6
6
|
</div>
|
|
7
7
|
<% else %>
|
|
8
8
|
<div class="overflow-x-auto">
|
|
9
|
-
<table class="min-w-full divide-y divide-gray-200">
|
|
10
|
-
<thead class="bg-gray-50">
|
|
9
|
+
<table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
10
|
+
<thead class="bg-gray-50 dark:bg-gray-900">
|
|
11
11
|
<tr>
|
|
12
12
|
<th
|
|
13
13
|
scope="col"
|
|
14
14
|
class="
|
|
15
|
-
px-4 py-3 text-left text-xs font-medium text-gray-500
|
|
15
|
+
px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400
|
|
16
16
|
uppercase tracking-wider
|
|
17
17
|
"
|
|
18
18
|
>
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<th
|
|
23
23
|
scope="col"
|
|
24
24
|
class="
|
|
25
|
-
px-4 py-3 text-left text-xs font-medium text-gray-500
|
|
25
|
+
px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400
|
|
26
26
|
uppercase tracking-wider
|
|
27
27
|
"
|
|
28
28
|
>
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
<th
|
|
33
33
|
scope="col"
|
|
34
34
|
class="
|
|
35
|
-
px-4 py-3 text-left text-xs font-medium text-gray-500
|
|
35
|
+
px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400
|
|
36
36
|
uppercase tracking-wider
|
|
37
37
|
"
|
|
38
38
|
>
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
<th
|
|
43
43
|
scope="col"
|
|
44
44
|
class="
|
|
45
|
-
px-4 py-3 text-right text-xs font-medium text-gray-500
|
|
45
|
+
px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400
|
|
46
46
|
uppercase tracking-wider
|
|
47
47
|
"
|
|
48
48
|
>
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
<th
|
|
53
53
|
scope="col"
|
|
54
54
|
class="
|
|
55
|
-
px-4 py-3 text-right text-xs font-medium text-gray-500
|
|
55
|
+
px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400
|
|
56
56
|
uppercase tracking-wider
|
|
57
57
|
"
|
|
58
58
|
>
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
<th
|
|
63
63
|
scope="col"
|
|
64
64
|
class="
|
|
65
|
-
px-4 py-3 text-right text-xs font-medium text-gray-500
|
|
65
|
+
px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400
|
|
66
66
|
uppercase tracking-wider
|
|
67
67
|
"
|
|
68
68
|
>
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
<th
|
|
73
73
|
scope="col"
|
|
74
74
|
class="
|
|
75
|
-
px-4 py-3 text-right text-xs font-medium text-gray-500
|
|
75
|
+
px-4 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400
|
|
76
76
|
uppercase tracking-wider
|
|
77
77
|
"
|
|
78
78
|
>
|
|
@@ -81,14 +81,14 @@
|
|
|
81
81
|
</tr>
|
|
82
82
|
</thead>
|
|
83
83
|
|
|
84
|
-
<tbody class="bg-white divide-y divide-gray-100">
|
|
84
|
+
<tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-100 dark:divide-gray-700">
|
|
85
85
|
<% executions.each do |execution| %>
|
|
86
86
|
<tr
|
|
87
|
-
class="hover:bg-gray-50 transition-colors cursor-pointer"
|
|
87
|
+
class="hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors cursor-pointer"
|
|
88
88
|
onclick="window.location='<%= ruby_llm_agents.execution_path(execution) %>'"
|
|
89
89
|
>
|
|
90
90
|
<td class="px-4 py-3 whitespace-nowrap">
|
|
91
|
-
<span class="text-sm font-medium text-gray-900">
|
|
91
|
+
<span class="text-sm font-medium text-gray-900 dark:text-gray-100">
|
|
92
92
|
<%= execution.agent_type.gsub(/Agent$/, '') %>
|
|
93
93
|
</span>
|
|
94
94
|
</td>
|
|
@@ -97,13 +97,13 @@
|
|
|
97
97
|
<%= render "rubyllm/agents/shared/status_badge", status: execution.status %>
|
|
98
98
|
</td>
|
|
99
99
|
|
|
100
|
-
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500">
|
|
100
|
+
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
|
|
101
101
|
v<%= execution.agent_version %>
|
|
102
102
|
</td>
|
|
103
103
|
|
|
104
104
|
<td
|
|
105
105
|
class="
|
|
106
|
-
px-4 py-3 whitespace-nowrap text-sm text-gray-900
|
|
106
|
+
px-4 py-3 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100
|
|
107
107
|
text-right font-medium
|
|
108
108
|
"
|
|
109
109
|
>
|
|
@@ -112,7 +112,7 @@
|
|
|
112
112
|
|
|
113
113
|
<td
|
|
114
114
|
class="
|
|
115
|
-
px-4 py-3 whitespace-nowrap text-sm text-gray-900
|
|
115
|
+
px-4 py-3 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100
|
|
116
116
|
text-right font-medium
|
|
117
117
|
"
|
|
118
118
|
>
|
|
@@ -121,22 +121,22 @@
|
|
|
121
121
|
|
|
122
122
|
<td
|
|
123
123
|
class="
|
|
124
|
-
px-4 py-3 whitespace-nowrap text-sm text-gray-900
|
|
124
|
+
px-4 py-3 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100
|
|
125
125
|
text-right font-medium
|
|
126
126
|
"
|
|
127
127
|
>
|
|
128
128
|
<%= number_with_delimiter(execution.duration_ms || 0) %>ms
|
|
129
129
|
</td>
|
|
130
130
|
|
|
131
|
-
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500 text-right">
|
|
131
|
+
<td class="px-4 py-3 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400 text-right">
|
|
132
132
|
<%= time_ago_in_words(execution.created_at) %> ago
|
|
133
133
|
</td>
|
|
134
134
|
</tr>
|
|
135
135
|
|
|
136
136
|
<% if execution.status_error? && execution.error_message.present? %>
|
|
137
|
-
<tr class="bg-red-50">
|
|
137
|
+
<tr class="bg-red-50 dark:bg-red-900/30">
|
|
138
138
|
<td colspan="7" class="px-4 py-2">
|
|
139
|
-
<p class="text-xs text-red-600">
|
|
139
|
+
<p class="text-xs text-red-600 dark:text-red-400">
|
|
140
140
|
<span class="font-medium">
|
|
141
141
|
<%= execution.error_class %>:
|
|
142
142
|
</span>
|
|
@@ -158,20 +158,20 @@
|
|
|
158
158
|
|
|
159
159
|
from_record = ((current_page - 1) * per_page) + 1
|
|
160
160
|
to_record = [current_page * per_page, total_count].min %>
|
|
161
|
-
<div class="px-4 py-4 flex items-center justify-between border-t border-gray-100">
|
|
162
|
-
<p class="text-sm text-gray-500">
|
|
161
|
+
<div class="px-4 py-4 flex items-center justify-between border-t border-gray-100 dark:border-gray-700">
|
|
162
|
+
<p class="text-sm text-gray-500 dark:text-gray-400">
|
|
163
163
|
Showing <%= from_record %>-<%= to_record %> of
|
|
164
164
|
<%= number_with_delimiter(total_count) %> executions
|
|
165
165
|
</p>
|
|
166
166
|
|
|
167
167
|
<nav class="flex items-center space-x-1">
|
|
168
168
|
<% if current_page > 1 %>
|
|
169
|
-
<%= link_to "Previous", url_for(page: current_page - 1), data: { turbo_frame: "executions_content", turbo_action: "advance" }, 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" %>
|
|
169
|
+
<%= link_to "Previous", url_for(page: current_page - 1), data: { turbo_frame: "executions_content", turbo_action: "advance" }, 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" %>
|
|
170
170
|
<% else %>
|
|
171
171
|
<span
|
|
172
172
|
class="
|
|
173
|
-
px-3 py-1.5 text-sm font-medium text-gray-400 bg-gray-100
|
|
174
|
-
border border-gray-200 rounded-md cursor-not-allowed
|
|
173
|
+
px-3 py-1.5 text-sm font-medium text-gray-400 dark:text-gray-500 bg-gray-100 dark:bg-gray-800
|
|
174
|
+
border border-gray-200 dark:border-gray-700 rounded-md cursor-not-allowed
|
|
175
175
|
"
|
|
176
176
|
>
|
|
177
177
|
Previous
|
|
@@ -195,7 +195,7 @@
|
|
|
195
195
|
|
|
196
196
|
<% pages_to_show.each do |page| %>
|
|
197
197
|
<% if page == :gap %>
|
|
198
|
-
<span class="px-2 py-1.5 text-sm text-gray-500">...</span>
|
|
198
|
+
<span class="px-2 py-1.5 text-sm text-gray-500 dark:text-gray-400">...</span>
|
|
199
199
|
<% elsif page == current_page %>
|
|
200
200
|
<span
|
|
201
201
|
class="
|
|
@@ -206,17 +206,17 @@
|
|
|
206
206
|
<%= page %>
|
|
207
207
|
</span>
|
|
208
208
|
<% else %>
|
|
209
|
-
<%= link_to page, url_for(page: page), data: { turbo_frame: "executions_content", turbo_action: "advance" }, 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" %>
|
|
209
|
+
<%= link_to page, url_for(page: page), data: { turbo_frame: "executions_content", turbo_action: "advance" }, 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" %>
|
|
210
210
|
<% end %>
|
|
211
211
|
<% end %>
|
|
212
212
|
|
|
213
213
|
<% if current_page < total_pages %>
|
|
214
|
-
<%= link_to "Next", url_for(page: current_page + 1), data: { turbo_frame: "executions_content", turbo_action: "advance" }, 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" %>
|
|
214
|
+
<%= link_to "Next", url_for(page: current_page + 1), data: { turbo_frame: "executions_content", turbo_action: "advance" }, 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" %>
|
|
215
215
|
<% else %>
|
|
216
216
|
<span
|
|
217
217
|
class="
|
|
218
|
-
px-3 py-1.5 text-sm font-medium text-gray-400 bg-gray-100
|
|
219
|
-
border border-gray-200 rounded-md cursor-not-allowed
|
|
218
|
+
px-3 py-1.5 text-sm font-medium text-gray-400 dark:text-gray-500 bg-gray-100 dark:bg-gray-800
|
|
219
|
+
border border-gray-200 dark:border-gray-700 rounded-md cursor-not-allowed
|
|
220
220
|
"
|
|
221
221
|
>
|
|
222
222
|
Next
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<h2 class="text-2xl font-bold text-gray-900 mb-6">Executions</h2>
|
|
1
|
+
<h2 class="text-2xl font-bold text-gray-900 dark:text-gray-100 mb-6">Executions</h2>
|
|
2
2
|
|
|
3
3
|
<%= turbo_frame_tag "executions_content" do %>
|
|
4
4
|
<%= render partial: "rubyllm/agents/executions/filters", locals: { agent_types: @agent_types, filter_stats: @filter_stats } %>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<div class="mb-6">
|
|
2
|
-
<%= link_to ruby_llm_agents.executions_path, class: "inline-flex items-center text-sm text-gray-500 hover:text-gray-700" do %>
|
|
2
|
+
<%= link_to ruby_llm_agents.executions_path, class: "inline-flex items-center text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200" do %>
|
|
3
3
|
<svg
|
|
4
4
|
class="w-4 h-4 mr-1"
|
|
5
5
|
fill="none"
|
|
@@ -18,26 +18,26 @@
|
|
|
18
18
|
</div>
|
|
19
19
|
|
|
20
20
|
<!-- Header -->
|
|
21
|
-
<div class="bg-white border border-gray-200 rounded-xl p-6 mb-6">
|
|
21
|
+
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-6 mb-6">
|
|
22
22
|
<div class="flex items-center justify-between">
|
|
23
23
|
<div>
|
|
24
24
|
<div class="flex items-center gap-3">
|
|
25
|
-
<h2 class="text-xl font-bold text-gray-900">
|
|
25
|
+
<h2 class="text-xl font-bold text-gray-900 dark:text-gray-100">
|
|
26
26
|
<%= @execution.agent_type.gsub(/Agent$/, '') %>
|
|
27
27
|
</h2>
|
|
28
28
|
|
|
29
29
|
<%= render "rubyllm/agents/shared/status_badge", status: @execution.status, size: :md %>
|
|
30
30
|
</div>
|
|
31
31
|
|
|
32
|
-
<p class="text-sm text-gray-500 mt-1">
|
|
32
|
+
<p class="text-sm text-gray-500 dark:text-gray-400 mt-1">
|
|
33
33
|
Execution #<%= @execution.id %> · v<%= @execution.agent_version %>
|
|
34
34
|
</p>
|
|
35
35
|
</div>
|
|
36
36
|
|
|
37
|
-
<div class="text-right text-sm text-gray-500">
|
|
37
|
+
<div class="text-right text-sm text-gray-500 dark:text-gray-400">
|
|
38
38
|
<p><%= @execution.created_at.strftime("%b %d, %Y at %H:%M") %></p>
|
|
39
39
|
|
|
40
|
-
<p class="text-xs text-gray-400">
|
|
40
|
+
<p class="text-xs text-gray-400 dark:text-gray-500">
|
|
41
41
|
<%= time_ago_in_words(@execution.created_at) %> ago
|
|
42
42
|
</p>
|
|
43
43
|
</div>
|
|
@@ -72,8 +72,8 @@
|
|
|
72
72
|
</div>
|
|
73
73
|
|
|
74
74
|
<!-- Token Breakdown -->
|
|
75
|
-
<div class="bg-white border border-gray-200 rounded-xl p-6 mb-6">
|
|
76
|
-
<h3 class="text-sm font-medium text-gray-500 uppercase tracking-wide mb-4">Token Usage</h3>
|
|
75
|
+
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-6 mb-6">
|
|
76
|
+
<h3 class="text-sm font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide mb-4">Token Usage</h3>
|
|
77
77
|
|
|
78
78
|
<!-- Token Distribution Bar -->
|
|
79
79
|
<%
|
|
@@ -85,67 +85,67 @@
|
|
|
85
85
|
%>
|
|
86
86
|
<div class="mb-6">
|
|
87
87
|
<div class="flex justify-between text-xs mb-1.5">
|
|
88
|
-
<span class="text-blue-600 font-medium">Input: <%= number_to_human_short(input_tokens) %> (<%= input_pct %>%)</span>
|
|
89
|
-
<span class="text-green-600 font-medium">Output: <%= number_to_human_short(output_tokens) %> (<%= output_pct %>%)</span>
|
|
88
|
+
<span class="text-blue-600 dark:text-blue-400 font-medium">Input: <%= number_to_human_short(input_tokens) %> (<%= input_pct %>%)</span>
|
|
89
|
+
<span class="text-green-600 dark:text-green-400 font-medium">Output: <%= number_to_human_short(output_tokens) %> (<%= output_pct %>%)</span>
|
|
90
90
|
</div>
|
|
91
|
-
<div class="h-2.5 bg-gray-100 rounded-full overflow-hidden flex">
|
|
91
|
+
<div class="h-2.5 bg-gray-100 dark:bg-gray-700 rounded-full overflow-hidden flex">
|
|
92
92
|
<div class="bg-blue-500 transition-all" style="width: <%= input_pct %>%"></div>
|
|
93
93
|
<div class="bg-green-500 transition-all" style="width: <%= output_pct %>%"></div>
|
|
94
94
|
</div>
|
|
95
95
|
</div>
|
|
96
96
|
|
|
97
97
|
<!-- Detailed Metrics -->
|
|
98
|
-
<div class="grid grid-cols-2 md:grid-cols-5 gap-6 pt-4 border-t border-gray-100">
|
|
98
|
+
<div class="grid grid-cols-2 md:grid-cols-5 gap-6 pt-4 border-t border-gray-100 dark:border-gray-700">
|
|
99
99
|
<div>
|
|
100
|
-
<p class="text-xs text-gray-500 uppercase tracking-wide">Input</p>
|
|
101
|
-
<p class="text-lg font-semibold text-gray-900"><%= number_to_human_short(@execution.input_tokens || 0) %></p>
|
|
102
|
-
<p class="text-xs text-gray-400"><%= number_to_human_short(@execution.input_cost || 0, prefix: "$", precision: 4) %></p>
|
|
100
|
+
<p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Input</p>
|
|
101
|
+
<p class="text-lg font-semibold text-gray-900 dark:text-gray-100"><%= number_to_human_short(@execution.input_tokens || 0) %></p>
|
|
102
|
+
<p class="text-xs text-gray-400 dark:text-gray-500"><%= number_to_human_short(@execution.input_cost || 0, prefix: "$", precision: 4) %></p>
|
|
103
103
|
</div>
|
|
104
104
|
|
|
105
105
|
<div>
|
|
106
|
-
<p class="text-xs text-gray-500 uppercase tracking-wide">Output</p>
|
|
107
|
-
<p class="text-lg font-semibold text-gray-900"><%= number_to_human_short(@execution.output_tokens || 0) %></p>
|
|
108
|
-
<p class="text-xs text-gray-400"><%= number_to_human_short(@execution.output_cost || 0, prefix: "$", precision: 4) %></p>
|
|
106
|
+
<p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Output</p>
|
|
107
|
+
<p class="text-lg font-semibold text-gray-900 dark:text-gray-100"><%= number_to_human_short(@execution.output_tokens || 0) %></p>
|
|
108
|
+
<p class="text-xs text-gray-400 dark:text-gray-500"><%= number_to_human_short(@execution.output_cost || 0, prefix: "$", precision: 4) %></p>
|
|
109
109
|
</div>
|
|
110
110
|
|
|
111
111
|
<div>
|
|
112
|
-
<p class="text-xs text-gray-500 uppercase tracking-wide">Cached</p>
|
|
113
|
-
<p class="text-lg font-semibold text-gray-900"><%= number_to_human_short(@execution.cached_tokens || 0) %></p>
|
|
112
|
+
<p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Cached</p>
|
|
113
|
+
<p class="text-lg font-semibold text-gray-900 dark:text-gray-100"><%= number_to_human_short(@execution.cached_tokens || 0) %></p>
|
|
114
114
|
</div>
|
|
115
115
|
|
|
116
116
|
<div>
|
|
117
|
-
<p class="text-xs text-gray-500 uppercase tracking-wide">Cache Creation</p>
|
|
118
|
-
<p class="text-lg font-semibold text-gray-900"><%= number_to_human_short(@execution.cache_creation_tokens || 0) %></p>
|
|
117
|
+
<p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Cache Creation</p>
|
|
118
|
+
<p class="text-lg font-semibold text-gray-900 dark:text-gray-100"><%= number_to_human_short(@execution.cache_creation_tokens || 0) %></p>
|
|
119
119
|
</div>
|
|
120
120
|
|
|
121
121
|
<div>
|
|
122
|
-
<p class="text-xs text-gray-500 uppercase tracking-wide">Tokens/Sec</p>
|
|
123
|
-
<p class="text-lg font-semibold text-gray-900"><%= @execution.tokens_per_second || 'N/A' %></p>
|
|
122
|
+
<p class="text-xs text-gray-500 dark:text-gray-400 uppercase tracking-wide">Tokens/Sec</p>
|
|
123
|
+
<p class="text-lg font-semibold text-gray-900 dark:text-gray-100"><%= @execution.tokens_per_second || 'N/A' %></p>
|
|
124
124
|
</div>
|
|
125
125
|
</div>
|
|
126
126
|
</div>
|
|
127
127
|
|
|
128
128
|
<% if @execution.status_error? %>
|
|
129
129
|
<!-- Error Details -->
|
|
130
|
-
<div class="bg-red-50 border border-red-200 rounded-lg p-6 mb-6">
|
|
131
|
-
<h3 class="text-lg font-semibold text-red-800 mb-2">Error Details</h3>
|
|
130
|
+
<div class="bg-red-50 dark:bg-red-900/30 border border-red-200 dark:border-red-800 rounded-lg p-6 mb-6">
|
|
131
|
+
<h3 class="text-lg font-semibold text-red-800 dark:text-red-300 mb-2">Error Details</h3>
|
|
132
132
|
|
|
133
|
-
<p class="font-mono text-sm text-red-700 mb-2">
|
|
133
|
+
<p class="font-mono text-sm text-red-700 dark:text-red-400 mb-2">
|
|
134
134
|
<%= @execution.error_class %>
|
|
135
135
|
</p>
|
|
136
136
|
|
|
137
|
-
<pre class="bg-red-100 rounded p-4 text-sm text-red-900 overflow-x-auto"><%= @execution.error_message %></pre>
|
|
137
|
+
<pre class="bg-red-100 dark:bg-red-900/50 rounded p-4 text-sm text-red-900 dark:text-red-200 overflow-x-auto"><%= @execution.error_message %></pre>
|
|
138
138
|
</div>
|
|
139
139
|
<% end %>
|
|
140
140
|
|
|
141
141
|
<!-- Parameters -->
|
|
142
|
-
<div class="bg-white border border-gray-200 rounded-xl p-6 mb-6">
|
|
142
|
+
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-6 mb-6">
|
|
143
143
|
<div class="flex items-center justify-between mb-4">
|
|
144
|
-
<h3 class="text-sm font-medium text-gray-500 uppercase tracking-wide">Parameters</h3>
|
|
144
|
+
<h3 class="text-sm font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">Parameters</h3>
|
|
145
145
|
<button
|
|
146
146
|
type="button"
|
|
147
147
|
data-copy-json="<%= Base64.strict_encode64(JSON.pretty_generate(@execution.parameters || {})) %>"
|
|
148
|
-
class="copy-json-btn inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-md transition-colors"
|
|
148
|
+
class="copy-json-btn inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-md transition-colors"
|
|
149
149
|
>
|
|
150
150
|
<svg class="w-4 h-4 copy-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
151
151
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
|
@@ -156,18 +156,18 @@
|
|
|
156
156
|
<span>Copy</span>
|
|
157
157
|
</button>
|
|
158
158
|
</div>
|
|
159
|
-
<pre class="bg-gray-50 rounded-lg p-4 text-sm overflow-x-auto font-mono"><%= highlight_json(@execution.parameters || {}) %></pre>
|
|
159
|
+
<pre class="bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 rounded-lg p-4 text-sm overflow-x-auto font-mono"><%= highlight_json(@execution.parameters || {}) %></pre>
|
|
160
160
|
</div>
|
|
161
161
|
|
|
162
162
|
<!-- Response -->
|
|
163
163
|
<% if @execution.response.present? %>
|
|
164
|
-
<div class="bg-white border border-gray-200 rounded-xl p-6 mb-6">
|
|
164
|
+
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-6 mb-6">
|
|
165
165
|
<div class="flex items-center justify-between mb-4">
|
|
166
|
-
<h3 class="text-sm font-medium text-gray-500 uppercase tracking-wide">Response</h3>
|
|
166
|
+
<h3 class="text-sm font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">Response</h3>
|
|
167
167
|
<button
|
|
168
168
|
type="button"
|
|
169
169
|
data-copy-json="<%= Base64.strict_encode64(JSON.pretty_generate(@execution.response)) %>"
|
|
170
|
-
class="copy-json-btn inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-md transition-colors"
|
|
170
|
+
class="copy-json-btn inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-md transition-colors"
|
|
171
171
|
>
|
|
172
172
|
<svg class="w-4 h-4 copy-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
173
173
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
|
@@ -178,19 +178,19 @@
|
|
|
178
178
|
<span>Copy</span>
|
|
179
179
|
</button>
|
|
180
180
|
</div>
|
|
181
|
-
<pre class="bg-gray-50 rounded-lg p-4 text-sm overflow-x-auto max-h-96 font-mono"><%= highlight_json(@execution.response) %></pre>
|
|
181
|
+
<pre class="bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 rounded-lg p-4 text-sm overflow-x-auto max-h-96 font-mono"><%= highlight_json(@execution.response) %></pre>
|
|
182
182
|
</div>
|
|
183
183
|
<% end %>
|
|
184
184
|
|
|
185
185
|
<!-- Metadata -->
|
|
186
186
|
<% if @execution.metadata.present? && @execution.metadata.any? %>
|
|
187
|
-
<div class="bg-white border border-gray-200 rounded-xl p-6 mb-6">
|
|
187
|
+
<div class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-xl p-6 mb-6">
|
|
188
188
|
<div class="flex items-center justify-between mb-4">
|
|
189
|
-
<h3 class="text-sm font-medium text-gray-500 uppercase tracking-wide">Metadata</h3>
|
|
189
|
+
<h3 class="text-sm font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide">Metadata</h3>
|
|
190
190
|
<button
|
|
191
191
|
type="button"
|
|
192
192
|
data-copy-json="<%= Base64.strict_encode64(JSON.pretty_generate(@execution.metadata)) %>"
|
|
193
|
-
class="copy-json-btn inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-gray-500 hover:text-gray-700 hover:bg-gray-100 rounded-md transition-colors"
|
|
193
|
+
class="copy-json-btn inline-flex items-center gap-1.5 px-2.5 py-1.5 text-xs font-medium text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-md transition-colors"
|
|
194
194
|
>
|
|
195
195
|
<svg class="w-4 h-4 copy-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
196
196
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z"/>
|
|
@@ -201,7 +201,7 @@
|
|
|
201
201
|
<span>Copy</span>
|
|
202
202
|
</button>
|
|
203
203
|
</div>
|
|
204
|
-
<pre class="bg-gray-50 rounded-lg p-4 text-sm overflow-x-auto font-mono"><%= highlight_json(@execution.metadata) %></pre>
|
|
204
|
+
<pre class="bg-gray-50 dark:bg-gray-900 text-gray-900 dark:text-gray-100 rounded-lg p-4 text-sm overflow-x-auto font-mono"><%= highlight_json(@execution.metadata) %></pre>
|
|
205
205
|
</div>
|
|
206
206
|
<% end %>
|
|
207
207
|
|