local-deep-research 0.5.9__py3-none-any.whl → 0.6.0__py3-none-any.whl
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.
- local_deep_research/__version__.py +1 -1
- local_deep_research/advanced_search_system/candidate_exploration/progressive_explorer.py +11 -1
- local_deep_research/advanced_search_system/questions/browsecomp_question.py +32 -6
- local_deep_research/advanced_search_system/strategies/focused_iteration_strategy.py +32 -8
- local_deep_research/advanced_search_system/strategies/source_based_strategy.py +2 -0
- local_deep_research/api/__init__.py +2 -0
- local_deep_research/api/research_functions.py +177 -3
- local_deep_research/benchmarks/graders.py +150 -5
- local_deep_research/benchmarks/models/__init__.py +19 -0
- local_deep_research/benchmarks/models/benchmark_models.py +283 -0
- local_deep_research/benchmarks/ui/__init__.py +1 -0
- local_deep_research/benchmarks/web_api/__init__.py +6 -0
- local_deep_research/benchmarks/web_api/benchmark_routes.py +862 -0
- local_deep_research/benchmarks/web_api/benchmark_service.py +920 -0
- local_deep_research/config/llm_config.py +106 -21
- local_deep_research/defaults/default_settings.json +447 -2
- local_deep_research/error_handling/report_generator.py +10 -0
- local_deep_research/llm/__init__.py +19 -0
- local_deep_research/llm/llm_registry.py +155 -0
- local_deep_research/metrics/db_models.py +3 -7
- local_deep_research/metrics/search_tracker.py +25 -11
- local_deep_research/search_system.py +12 -9
- local_deep_research/utilities/log_utils.py +23 -10
- local_deep_research/utilities/thread_context.py +99 -0
- local_deep_research/web/app_factory.py +32 -8
- local_deep_research/web/database/benchmark_schema.py +230 -0
- local_deep_research/web/database/convert_research_id_to_string.py +161 -0
- local_deep_research/web/database/models.py +55 -1
- local_deep_research/web/database/schema_upgrade.py +397 -2
- local_deep_research/web/database/uuid_migration.py +265 -0
- local_deep_research/web/routes/api_routes.py +62 -31
- local_deep_research/web/routes/history_routes.py +13 -6
- local_deep_research/web/routes/metrics_routes.py +264 -4
- local_deep_research/web/routes/research_routes.py +45 -18
- local_deep_research/web/routes/route_registry.py +352 -0
- local_deep_research/web/routes/settings_routes.py +382 -22
- local_deep_research/web/services/research_service.py +22 -29
- local_deep_research/web/services/settings_manager.py +53 -0
- local_deep_research/web/services/settings_service.py +2 -0
- local_deep_research/web/static/css/styles.css +8 -0
- local_deep_research/web/static/js/components/detail.js +7 -14
- local_deep_research/web/static/js/components/details.js +8 -10
- local_deep_research/web/static/js/components/fallback/ui.js +4 -4
- local_deep_research/web/static/js/components/history.js +6 -6
- local_deep_research/web/static/js/components/logpanel.js +14 -11
- local_deep_research/web/static/js/components/progress.js +51 -46
- local_deep_research/web/static/js/components/research.js +250 -89
- local_deep_research/web/static/js/components/results.js +5 -7
- local_deep_research/web/static/js/components/settings.js +32 -26
- local_deep_research/web/static/js/components/settings_sync.js +24 -23
- local_deep_research/web/static/js/config/urls.js +285 -0
- local_deep_research/web/static/js/main.js +8 -8
- local_deep_research/web/static/js/research_form.js +267 -12
- local_deep_research/web/static/js/services/api.js +18 -18
- local_deep_research/web/static/js/services/keyboard.js +8 -8
- local_deep_research/web/static/js/services/socket.js +53 -35
- local_deep_research/web/static/js/services/ui.js +1 -1
- local_deep_research/web/templates/base.html +4 -1
- local_deep_research/web/templates/components/custom_dropdown.html +5 -3
- local_deep_research/web/templates/components/mobile_nav.html +3 -3
- local_deep_research/web/templates/components/sidebar.html +9 -3
- local_deep_research/web/templates/pages/benchmark.html +2697 -0
- local_deep_research/web/templates/pages/benchmark_results.html +1136 -0
- local_deep_research/web/templates/pages/benchmark_simple.html +453 -0
- local_deep_research/web/templates/pages/cost_analytics.html +1 -1
- local_deep_research/web/templates/pages/metrics.html +212 -39
- local_deep_research/web/templates/pages/research.html +8 -6
- local_deep_research/web/templates/pages/star_reviews.html +1 -1
- local_deep_research/web_search_engines/engines/search_engine_arxiv.py +14 -1
- local_deep_research/web_search_engines/engines/search_engine_brave.py +15 -1
- local_deep_research/web_search_engines/engines/search_engine_ddg.py +20 -1
- local_deep_research/web_search_engines/engines/search_engine_google_pse.py +26 -2
- local_deep_research/web_search_engines/engines/search_engine_pubmed.py +15 -1
- local_deep_research/web_search_engines/engines/search_engine_retriever.py +192 -0
- local_deep_research/web_search_engines/engines/search_engine_tavily.py +307 -0
- local_deep_research/web_search_engines/rate_limiting/__init__.py +14 -0
- local_deep_research/web_search_engines/rate_limiting/__main__.py +9 -0
- local_deep_research/web_search_engines/rate_limiting/cli.py +209 -0
- local_deep_research/web_search_engines/rate_limiting/exceptions.py +21 -0
- local_deep_research/web_search_engines/rate_limiting/tracker.py +506 -0
- local_deep_research/web_search_engines/retriever_registry.py +108 -0
- local_deep_research/web_search_engines/search_engine_base.py +161 -43
- local_deep_research/web_search_engines/search_engine_factory.py +14 -0
- local_deep_research/web_search_engines/search_engines_config.py +20 -0
- local_deep_research-0.6.0.dist-info/METADATA +374 -0
- {local_deep_research-0.5.9.dist-info → local_deep_research-0.6.0.dist-info}/RECORD +89 -64
- local_deep_research-0.5.9.dist-info/METADATA +0 -420
- {local_deep_research-0.5.9.dist-info → local_deep_research-0.6.0.dist-info}/WHEEL +0 -0
- {local_deep_research-0.5.9.dist-info → local_deep_research-0.6.0.dist-info}/entry_points.txt +0 -0
- {local_deep_research-0.5.9.dist-info → local_deep_research-0.6.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,453 @@
|
|
1
|
+
{% extends "base.html" %}
|
2
|
+
|
3
|
+
{% set active_page = 'benchmark' %}
|
4
|
+
|
5
|
+
{% block title %}Benchmark - Deep Research System{% endblock %}
|
6
|
+
|
7
|
+
{% block extra_head %}
|
8
|
+
<meta name="csrf-token" content="{{ csrf_token() }}">
|
9
|
+
<style>
|
10
|
+
.benchmark-card {
|
11
|
+
max-width: 700px;
|
12
|
+
margin: 0 auto;
|
13
|
+
}
|
14
|
+
|
15
|
+
.current-config {
|
16
|
+
background: var(--bg-color);
|
17
|
+
border: 1px solid var(--border-color);
|
18
|
+
border-radius: 8px;
|
19
|
+
padding: 20px;
|
20
|
+
margin-bottom: 20px;
|
21
|
+
}
|
22
|
+
|
23
|
+
.config-item {
|
24
|
+
display: flex;
|
25
|
+
justify-content: space-between;
|
26
|
+
padding: 8px 0;
|
27
|
+
border-bottom: 1px solid var(--border-color);
|
28
|
+
}
|
29
|
+
|
30
|
+
.config-item:last-child {
|
31
|
+
border-bottom: none;
|
32
|
+
}
|
33
|
+
|
34
|
+
.config-label {
|
35
|
+
font-weight: 500;
|
36
|
+
color: var(--text-muted);
|
37
|
+
}
|
38
|
+
|
39
|
+
.config-value {
|
40
|
+
font-weight: 600;
|
41
|
+
color: var(--primary-color);
|
42
|
+
}
|
43
|
+
|
44
|
+
.dataset-selection {
|
45
|
+
margin: 20px 0;
|
46
|
+
}
|
47
|
+
|
48
|
+
.dataset-option {
|
49
|
+
display: flex;
|
50
|
+
align-items: center;
|
51
|
+
padding: 15px;
|
52
|
+
margin: 10px 0;
|
53
|
+
background: var(--card-bg);
|
54
|
+
border: 2px solid var(--border-color);
|
55
|
+
border-radius: 8px;
|
56
|
+
cursor: pointer;
|
57
|
+
transition: all 0.2s;
|
58
|
+
}
|
59
|
+
|
60
|
+
.dataset-option:hover {
|
61
|
+
border-color: var(--primary-color);
|
62
|
+
}
|
63
|
+
|
64
|
+
.dataset-option.selected {
|
65
|
+
border-color: var(--primary-color);
|
66
|
+
background: var(--primary-light);
|
67
|
+
}
|
68
|
+
|
69
|
+
.dataset-option input[type="number"] {
|
70
|
+
width: 80px;
|
71
|
+
margin-left: auto;
|
72
|
+
}
|
73
|
+
|
74
|
+
.start-button {
|
75
|
+
width: 100%;
|
76
|
+
padding: 15px;
|
77
|
+
font-size: 1.1rem;
|
78
|
+
}
|
79
|
+
|
80
|
+
.progress-section {
|
81
|
+
display: none;
|
82
|
+
margin-top: 30px;
|
83
|
+
}
|
84
|
+
|
85
|
+
.progress-bar {
|
86
|
+
width: 100%;
|
87
|
+
height: 30px;
|
88
|
+
background: var(--bg-color);
|
89
|
+
border-radius: 15px;
|
90
|
+
overflow: hidden;
|
91
|
+
margin: 20px 0;
|
92
|
+
}
|
93
|
+
|
94
|
+
.progress-fill {
|
95
|
+
height: 100%;
|
96
|
+
background: linear-gradient(90deg, var(--primary-color), var(--accent-color));
|
97
|
+
width: 0%;
|
98
|
+
transition: width 0.3s ease;
|
99
|
+
}
|
100
|
+
|
101
|
+
.stats-grid {
|
102
|
+
display: grid;
|
103
|
+
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
|
104
|
+
gap: 15px;
|
105
|
+
margin-top: 20px;
|
106
|
+
}
|
107
|
+
|
108
|
+
.stat-card {
|
109
|
+
padding: 15px;
|
110
|
+
background: var(--bg-color);
|
111
|
+
border-radius: 8px;
|
112
|
+
text-align: center;
|
113
|
+
}
|
114
|
+
|
115
|
+
.stat-value {
|
116
|
+
font-size: 1.8rem;
|
117
|
+
font-weight: bold;
|
118
|
+
color: var(--primary-color);
|
119
|
+
}
|
120
|
+
|
121
|
+
.stat-label {
|
122
|
+
font-size: 0.9rem;
|
123
|
+
color: var(--text-muted);
|
124
|
+
margin-top: 5px;
|
125
|
+
}
|
126
|
+
</style>
|
127
|
+
{% endblock %}
|
128
|
+
|
129
|
+
{% block content %}
|
130
|
+
<div class="page active" id="benchmark">
|
131
|
+
<div class="page-header">
|
132
|
+
<h1>Benchmark Your Configuration</h1>
|
133
|
+
<p class="page-subtitle">Test your current settings against standard datasets</p>
|
134
|
+
</div>
|
135
|
+
|
136
|
+
<div id="benchmark-alert" class="settings-alert-container" style="display:none"></div>
|
137
|
+
|
138
|
+
<div class="card benchmark-card">
|
139
|
+
<div class="card-content">
|
140
|
+
<!-- Current Configuration Display -->
|
141
|
+
<div class="current-config">
|
142
|
+
<h3>Current Configuration</h3>
|
143
|
+
<div id="config-display">
|
144
|
+
<div class="config-item">
|
145
|
+
<span class="config-label">Loading...</span>
|
146
|
+
<span class="config-value"></span>
|
147
|
+
</div>
|
148
|
+
</div>
|
149
|
+
</div>
|
150
|
+
|
151
|
+
<!-- Dataset Selection -->
|
152
|
+
<div class="dataset-selection">
|
153
|
+
<h3>Select Datasets to Test</h3>
|
154
|
+
|
155
|
+
<div class="dataset-option selected" data-dataset="simpleqa">
|
156
|
+
<div>
|
157
|
+
<h4>SimpleQA</h4>
|
158
|
+
<p>Fact-based questions with clear answers</p>
|
159
|
+
</div>
|
160
|
+
<input type="number" id="simpleqa_count" value="20" min="1" max="500">
|
161
|
+
</div>
|
162
|
+
|
163
|
+
<div class="dataset-option selected" data-dataset="browsecomp">
|
164
|
+
<div>
|
165
|
+
<h4>BrowseComp</h4>
|
166
|
+
<p>Complex browsing and comparison tasks</p>
|
167
|
+
</div>
|
168
|
+
<input type="number" id="browsecomp_count" value="10" min="1" max="200">
|
169
|
+
</div>
|
170
|
+
</div>
|
171
|
+
|
172
|
+
<!-- Start Button -->
|
173
|
+
<button type="button" id="start-benchmark" class="btn btn-primary start-button">
|
174
|
+
<i class="fas fa-play"></i> Start Benchmark
|
175
|
+
</button>
|
176
|
+
|
177
|
+
<!-- Progress Section -->
|
178
|
+
<div class="progress-section" id="progress-section">
|
179
|
+
<h3>Benchmark Progress</h3>
|
180
|
+
|
181
|
+
<div class="progress-bar">
|
182
|
+
<div class="progress-fill" id="progress-fill"></div>
|
183
|
+
</div>
|
184
|
+
|
185
|
+
<div class="stats-grid">
|
186
|
+
<div class="stat-card">
|
187
|
+
<div class="stat-value" id="stat-accuracy">--%</div>
|
188
|
+
<div class="stat-label">Accuracy</div>
|
189
|
+
</div>
|
190
|
+
<div class="stat-card">
|
191
|
+
<div class="stat-value" id="stat-completed">0</div>
|
192
|
+
<div class="stat-label">Completed</div>
|
193
|
+
</div>
|
194
|
+
<div class="stat-card">
|
195
|
+
<div class="stat-value" id="stat-rate">--</div>
|
196
|
+
<div class="stat-label">Per Minute</div>
|
197
|
+
</div>
|
198
|
+
<div class="stat-card">
|
199
|
+
<div class="stat-value" id="stat-remaining">--</div>
|
200
|
+
<div class="stat-label">Time Left</div>
|
201
|
+
</div>
|
202
|
+
</div>
|
203
|
+
|
204
|
+
<div style="margin-top: 20px; text-align: center;">
|
205
|
+
<button type="button" id="cancel-benchmark" class="btn btn-secondary">
|
206
|
+
<i class="fas fa-stop"></i> Cancel
|
207
|
+
</button>
|
208
|
+
</div>
|
209
|
+
</div>
|
210
|
+
</div>
|
211
|
+
</div>
|
212
|
+
</div>
|
213
|
+
|
214
|
+
<script>
|
215
|
+
let currentBenchmarkId = null;
|
216
|
+
let progressInterval = null;
|
217
|
+
|
218
|
+
document.addEventListener('DOMContentLoaded', function() {
|
219
|
+
loadCurrentConfig();
|
220
|
+
setupEventListeners();
|
221
|
+
});
|
222
|
+
|
223
|
+
async function loadCurrentConfig() {
|
224
|
+
try {
|
225
|
+
// Get current settings from the database
|
226
|
+
const response = await fetch('/research/settings/api');
|
227
|
+
const data = await response.json();
|
228
|
+
|
229
|
+
if (data.settings) {
|
230
|
+
const config = {
|
231
|
+
provider: data.settings['llm.provider']?.value || 'Not configured',
|
232
|
+
model: data.settings['llm.model']?.value || 'Not configured',
|
233
|
+
search_tool: data.settings['search.tool']?.value || 'searxng',
|
234
|
+
iterations: data.settings['search.iterations']?.value || '8',
|
235
|
+
questions_per_iteration: data.settings['search.questions_per_iteration']?.value || '5',
|
236
|
+
search_strategy: data.settings['search.search_strategy']?.value || 'focused_iteration'
|
237
|
+
};
|
238
|
+
displayConfig(config);
|
239
|
+
}
|
240
|
+
} catch (error) {
|
241
|
+
console.error('Error loading config:', error);
|
242
|
+
// Use fallback display
|
243
|
+
displayConfig({
|
244
|
+
provider: 'Loading...',
|
245
|
+
model: 'Loading...',
|
246
|
+
search_tool: 'Loading...',
|
247
|
+
iterations: '-'
|
248
|
+
});
|
249
|
+
}
|
250
|
+
}
|
251
|
+
|
252
|
+
function displayConfig(config) {
|
253
|
+
const configDisplay = document.getElementById('config-display');
|
254
|
+
configDisplay.innerHTML = `
|
255
|
+
<div class="config-item">
|
256
|
+
<span class="config-label">LLM Provider</span>
|
257
|
+
<span class="config-value">${config.provider || 'Not set'}</span>
|
258
|
+
</div>
|
259
|
+
<div class="config-item">
|
260
|
+
<span class="config-label">Model</span>
|
261
|
+
<span class="config-value">${config.model || 'Not set'}</span>
|
262
|
+
</div>
|
263
|
+
<div class="config-item">
|
264
|
+
<span class="config-label">Search Engine</span>
|
265
|
+
<span class="config-value">${config.search_tool || 'searxng'}</span>
|
266
|
+
</div>
|
267
|
+
<div class="config-item">
|
268
|
+
<span class="config-label">Search Iterations</span>
|
269
|
+
<span class="config-value">${config.iterations || '8'}</span>
|
270
|
+
</div>
|
271
|
+
`;
|
272
|
+
}
|
273
|
+
|
274
|
+
function setupEventListeners() {
|
275
|
+
// Dataset selection
|
276
|
+
document.querySelectorAll('.dataset-option').forEach(option => {
|
277
|
+
option.addEventListener('click', function(e) {
|
278
|
+
if (!e.target.matches('input')) {
|
279
|
+
this.classList.toggle('selected');
|
280
|
+
}
|
281
|
+
});
|
282
|
+
});
|
283
|
+
|
284
|
+
// Start benchmark
|
285
|
+
document.getElementById('start-benchmark').addEventListener('click', startBenchmark);
|
286
|
+
|
287
|
+
// Cancel benchmark
|
288
|
+
document.getElementById('cancel-benchmark').addEventListener('click', cancelBenchmark);
|
289
|
+
}
|
290
|
+
|
291
|
+
async function startBenchmark() {
|
292
|
+
// Get dataset configuration
|
293
|
+
const datasets = {};
|
294
|
+
document.querySelectorAll('.dataset-option.selected').forEach(option => {
|
295
|
+
const dataset = option.getAttribute('data-dataset');
|
296
|
+
const count = parseInt(option.querySelector('input').value) || 0;
|
297
|
+
if (count > 0) {
|
298
|
+
datasets[dataset] = { count: count };
|
299
|
+
}
|
300
|
+
});
|
301
|
+
|
302
|
+
if (Object.keys(datasets).length === 0) {
|
303
|
+
showAlert('Please select at least one dataset', 'error');
|
304
|
+
return;
|
305
|
+
}
|
306
|
+
|
307
|
+
// Disable start button
|
308
|
+
document.getElementById('start-benchmark').disabled = true;
|
309
|
+
|
310
|
+
try {
|
311
|
+
// Get CSRF token
|
312
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
313
|
+
|
314
|
+
const response = await fetch('/benchmark/api/start-simple', {
|
315
|
+
method: 'POST',
|
316
|
+
headers: {
|
317
|
+
'Content-Type': 'application/json',
|
318
|
+
'X-CSRFToken': csrfToken
|
319
|
+
},
|
320
|
+
body: JSON.stringify({ datasets_config: datasets })
|
321
|
+
});
|
322
|
+
|
323
|
+
const data = await response.json();
|
324
|
+
|
325
|
+
if (data.success) {
|
326
|
+
currentBenchmarkId = data.benchmark_run_id;
|
327
|
+
showProgress();
|
328
|
+
startProgressTracking();
|
329
|
+
showAlert('Benchmark started!', 'success');
|
330
|
+
} else {
|
331
|
+
showAlert('Error: ' + data.error, 'error');
|
332
|
+
document.getElementById('start-benchmark').disabled = false;
|
333
|
+
}
|
334
|
+
} catch (error) {
|
335
|
+
console.error('Error starting benchmark:', error);
|
336
|
+
showAlert('Failed to start benchmark', 'error');
|
337
|
+
document.getElementById('start-benchmark').disabled = false;
|
338
|
+
}
|
339
|
+
}
|
340
|
+
|
341
|
+
function showProgress() {
|
342
|
+
document.querySelector('.dataset-selection').style.display = 'none';
|
343
|
+
document.getElementById('start-benchmark').style.display = 'none';
|
344
|
+
document.getElementById('progress-section').style.display = 'block';
|
345
|
+
}
|
346
|
+
|
347
|
+
function hideProgress() {
|
348
|
+
document.querySelector('.dataset-selection').style.display = 'block';
|
349
|
+
document.getElementById('start-benchmark').style.display = 'block';
|
350
|
+
document.getElementById('progress-section').style.display = 'none';
|
351
|
+
document.getElementById('start-benchmark').disabled = false;
|
352
|
+
}
|
353
|
+
|
354
|
+
function startProgressTracking() {
|
355
|
+
updateProgress(); // Initial update
|
356
|
+
progressInterval = setInterval(updateProgress, 2000);
|
357
|
+
}
|
358
|
+
|
359
|
+
async function updateProgress() {
|
360
|
+
if (!currentBenchmarkId) return;
|
361
|
+
|
362
|
+
try {
|
363
|
+
const response = await fetch(`/benchmark/api/status/${currentBenchmarkId}`);
|
364
|
+
const data = await response.json();
|
365
|
+
|
366
|
+
if (data.success) {
|
367
|
+
const status = data.status;
|
368
|
+
|
369
|
+
// Update progress bar
|
370
|
+
const percentage = status.total_examples > 0 ?
|
371
|
+
(status.completed_examples / status.total_examples * 100) : 0;
|
372
|
+
document.getElementById('progress-fill').style.width = percentage + '%';
|
373
|
+
|
374
|
+
// Update stats
|
375
|
+
document.getElementById('stat-accuracy').textContent =
|
376
|
+
status.overall_accuracy ? status.overall_accuracy.toFixed(1) + '%' : '--%';
|
377
|
+
document.getElementById('stat-completed').textContent =
|
378
|
+
`${status.completed_examples}/${status.total_examples}`;
|
379
|
+
document.getElementById('stat-rate').textContent =
|
380
|
+
status.processing_rate ? status.processing_rate.toFixed(1) : '--';
|
381
|
+
|
382
|
+
// Estimate remaining time
|
383
|
+
if (status.processing_rate > 0 && status.completed_examples < status.total_examples) {
|
384
|
+
const remaining = status.total_examples - status.completed_examples;
|
385
|
+
const minutes = Math.ceil(remaining / status.processing_rate);
|
386
|
+
document.getElementById('stat-remaining').textContent = `${minutes}m`;
|
387
|
+
} else {
|
388
|
+
document.getElementById('stat-remaining').textContent = '--';
|
389
|
+
}
|
390
|
+
|
391
|
+
// Check if completed
|
392
|
+
if (status.status === 'completed' || status.status === 'failed' || status.status === 'cancelled') {
|
393
|
+
clearInterval(progressInterval);
|
394
|
+
progressInterval = null;
|
395
|
+
|
396
|
+
if (status.status === 'completed') {
|
397
|
+
showAlert(`Benchmark completed! Final accuracy: ${status.overall_accuracy.toFixed(1)}%`, 'success');
|
398
|
+
} else {
|
399
|
+
showAlert(`Benchmark ${status.status}`, 'error');
|
400
|
+
}
|
401
|
+
|
402
|
+
setTimeout(() => {
|
403
|
+
hideProgress();
|
404
|
+
currentBenchmarkId = null;
|
405
|
+
}, 3000);
|
406
|
+
}
|
407
|
+
}
|
408
|
+
} catch (error) {
|
409
|
+
console.error('Error updating progress:', error);
|
410
|
+
}
|
411
|
+
}
|
412
|
+
|
413
|
+
async function cancelBenchmark() {
|
414
|
+
if (!currentBenchmarkId) return;
|
415
|
+
|
416
|
+
try {
|
417
|
+
const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
|
418
|
+
const response = await fetch(`/benchmark/api/cancel/${currentBenchmarkId}`, {
|
419
|
+
method: 'POST',
|
420
|
+
headers: {
|
421
|
+
'X-CSRFToken': csrfToken
|
422
|
+
}
|
423
|
+
});
|
424
|
+
|
425
|
+
const data = await response.json();
|
426
|
+
if (data.success) {
|
427
|
+
showAlert('Benchmark cancelled', 'info');
|
428
|
+
}
|
429
|
+
} catch (error) {
|
430
|
+
console.error('Error cancelling benchmark:', error);
|
431
|
+
}
|
432
|
+
}
|
433
|
+
|
434
|
+
function showAlert(message, type) {
|
435
|
+
const alertContainer = document.getElementById('benchmark-alert');
|
436
|
+
alertContainer.innerHTML = `
|
437
|
+
<div class="settings-alert alert-${type}">
|
438
|
+
<span>${message}</span>
|
439
|
+
<button type="button" class="close-alert" onclick="this.parentElement.parentElement.style.display='none'">
|
440
|
+
<i class="fas fa-times"></i>
|
441
|
+
</button>
|
442
|
+
</div>
|
443
|
+
`;
|
444
|
+
alertContainer.style.display = 'block';
|
445
|
+
|
446
|
+
if (type === 'success') {
|
447
|
+
setTimeout(() => {
|
448
|
+
alertContainer.style.display = 'none';
|
449
|
+
}, 5000);
|
450
|
+
}
|
451
|
+
}
|
452
|
+
</script>
|
453
|
+
{% endblock %}
|
@@ -1094,7 +1094,7 @@
|
|
1094
1094
|
div.innerHTML = `
|
1095
1095
|
<div class="cost-item-info">
|
1096
1096
|
<div class="cost-item-name">
|
1097
|
-
<a href="/
|
1097
|
+
<a href="/results/${item.research_id}" class="research-link">
|
1098
1098
|
Research Session #${item.research_id}
|
1099
1099
|
</a>
|
1100
1100
|
</div>
|