crewlyze 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +12 -0
- package/.gitattributes +2 -0
- package/CHANGELOG.md +86 -0
- package/Dockerfile +21 -0
- package/LICENSE +21 -0
- package/README.md +139 -0
- package/USAGE.md +106 -0
- package/agents/__init__.py +0 -0
- package/agents/cleaner.py +38 -0
- package/agents/insights.py +44 -0
- package/agents/relation.py +36 -0
- package/agents/visualizer.py +41 -0
- package/assets/badge_crewai.svg +4 -0
- package/assets/badge_matplotlib.svg +4 -0
- package/assets/badge_ollama.svg +4 -0
- package/assets/badge_pandas.svg +4 -0
- package/assets/badge_seaborn.svg +4 -0
- package/assets/branding_image.png +0 -0
- package/assets/complete_workflow.svg +216 -0
- package/assets/favicon.png +0 -0
- package/assets/logo.png +0 -0
- package/assets/stars.svg +12 -0
- package/bin/crewlyze.js +79 -0
- package/config/README.md +129 -0
- package/config/__init__.py +1 -0
- package/config/context.py +16 -0
- package/config/llm_config.py +300 -0
- package/config/metrics_tracker.py +70 -0
- package/crew.py +870 -0
- package/crewlyze-3.1.0.tgz +0 -0
- package/fix_syntax.py +54 -0
- package/main.py +1279 -0
- package/package.json +22 -0
- package/pyproject.toml +32 -0
- package/requirements.txt +33 -0
- package/tools/__init__.py +0 -0
- package/tools/dataset_tools.py +803 -0
- package/ui/__init__.py +3 -0
- package/ui/copilot.py +200 -0
- package/ui/export.py +800 -0
- package/update_appjs.py +54 -0
- package/update_llm.py +21 -0
- package/update_main.py +20 -0
- package/web/app.js +3142 -0
- package/web/index.html +1105 -0
- package/web/style.css +2561 -0
- package/workflows/__init__.py +0 -0
- package/workflows/pipeline.py +254 -0
package/web/index.html
ADDED
|
@@ -0,0 +1,1105 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="UTF-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
+
<title>Crewlyze — AI-Powered Business Intelligence</title>
|
|
8
|
+
<meta name="description"
|
|
9
|
+
content="Autonomous Multi-Agent AI system for data cleaning, relationship analysis, business insights, and interactive visualizations." />
|
|
10
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
11
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
12
|
+
<link
|
|
13
|
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap"
|
|
14
|
+
rel="stylesheet" />
|
|
15
|
+
<script src="https://cdn.plot.ly/plotly-2.35.2.min.js"></script>
|
|
16
|
+
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
|
17
|
+
<!-- Lucide Icons -->
|
|
18
|
+
<script src="https://unpkg.com/lucide@latest"></script>
|
|
19
|
+
<link rel="stylesheet" href="/style.css" />
|
|
20
|
+
<link rel="icon" type="image/png" href="/assets/favicon.png" />
|
|
21
|
+
</head>
|
|
22
|
+
|
|
23
|
+
<body>
|
|
24
|
+
|
|
25
|
+
<!-- ═══════════════════════════════ SIDEBAR ══════════════════════════════════ -->
|
|
26
|
+
<aside id="sidebar" class="sidebar">
|
|
27
|
+
<div class="sidebar-header">
|
|
28
|
+
<div class="logo" id="sidebarLogo" style="cursor: pointer;" title="Go to Dashboard">
|
|
29
|
+
<img src="/assets/logo.png" alt="Crewlyze Logo" style="height: 32px; object-fit: contain;" />
|
|
30
|
+
<span class="logo-text" style="margin-left: 8px;">Crew<span class="logo-accent">lyze</span></span>
|
|
31
|
+
</div>
|
|
32
|
+
<button id="sidebarToggle" class="sidebar-toggle" title="Collapse sidebar">‹</button>
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<!-- LLM Settings -->
|
|
36
|
+
<div class="sidebar-section">
|
|
37
|
+
<div class="sidebar-section-header"><span>LLM CONFIGURATION</span></div>
|
|
38
|
+
|
|
39
|
+
<label class="field-label">Provider</label>
|
|
40
|
+
<select id="llmProvider" class="field-select">
|
|
41
|
+
<option value="nvidia">NVIDIA NIM</option>
|
|
42
|
+
<option value="groq">Groq</option>
|
|
43
|
+
<option value="openai">OpenAI</option>
|
|
44
|
+
<option value="anthropic">Anthropic</option>
|
|
45
|
+
<option value="gemini">Google Gemini</option>
|
|
46
|
+
<option value="mistral">Mistral</option>
|
|
47
|
+
<option value="huggingface">HuggingFace</option>
|
|
48
|
+
<option value="ollama">Ollama (local)</option>
|
|
49
|
+
<option value="custom">Custom API (OpenAI Compatible)</option>
|
|
50
|
+
</select>
|
|
51
|
+
|
|
52
|
+
<label class="field-label">Model</label>
|
|
53
|
+
<select id="llmModel" class="field-select"></select>
|
|
54
|
+
<div id="sidebarApiKeyStatus"
|
|
55
|
+
style="font-size: 0.75rem; margin-top: 10px; text-align: center; display: flex; align-items: center; justify-content: center; gap: 6px;">
|
|
56
|
+
</div>
|
|
57
|
+
|
|
58
|
+
<!-- Hidden elements to ensure backward compatibility in app.js -->
|
|
59
|
+
<input type="hidden" id="apiKey" />
|
|
60
|
+
<input type="hidden" id="cooldown" value="5" />
|
|
61
|
+
<span id="cooldownVal" style="display: none;">5</span>
|
|
62
|
+
<span id="keyLabel" style="display: none;"></span>
|
|
63
|
+
<button id="testConnectionBtn" style="display: none;"></button>
|
|
64
|
+
<div id="connectionStatus" style="display: none;"></div>
|
|
65
|
+
</div>
|
|
66
|
+
|
|
67
|
+
<!-- Sidebar Project Actions -->
|
|
68
|
+
<div id="sidebarProjectActions" class="sidebar-section hidden"
|
|
69
|
+
style="margin-top: auto; border-top: 1px solid var(--border); padding-top: 15px;">
|
|
70
|
+
<div class="sidebar-section-header"><span>PROJECT ACTIONS</span></div>
|
|
71
|
+
<div style="display: flex; flex-direction: column; gap: 8px; margin-top: 8px;">
|
|
72
|
+
<button id="sidebarExportPdfBtn" class="sidebar-action-btn btn-primary"
|
|
73
|
+
style="width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; font-size: 0.8rem; padding: 10px 12px; border-radius: var(--r-sm); font-weight: 600; cursor: pointer;"><i
|
|
74
|
+
data-lucide="file-text" style="width: 14px; height: 14px;"></i> Export PDF Report</button>
|
|
75
|
+
<button id="sidebarExportZipBtn" class="sidebar-action-btn btn-secondary"
|
|
76
|
+
style="width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; font-size: 0.8rem; padding: 10px 12px; border-radius: var(--r-sm); font-weight: 600; cursor: pointer;"><i
|
|
77
|
+
data-lucide="archive" style="width: 14px; height: 14px;"></i> Export Project (.zip)</button>
|
|
78
|
+
<button id="sidebarDownloadCsvBtn" class="sidebar-action-btn btn-secondary"
|
|
79
|
+
style="width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; font-size: 0.8rem; padding: 10px 12px; border-radius: var(--r-sm); cursor: pointer; color: var(--text-primary); border: 1px solid var(--border-mid); background: var(--bg-elevated);"><i
|
|
80
|
+
data-lucide="download" style="width: 14px; height: 14px;"></i> Download Cleaned CSV</button>
|
|
81
|
+
<button id="sidebarReRunBtn" class="sidebar-action-btn btn-ghost"
|
|
82
|
+
style="width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; font-size: 0.8rem; padding: 10px 12px; border-radius: var(--r-sm); cursor: pointer; color: var(--text-secondary); background: transparent; border: 1px dashed var(--border-mid);"><i
|
|
83
|
+
data-lucide="refresh-cw" style="width: 14px; height: 14px;"></i> Re-run Analysis</button>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<div class="sidebar-footer">
|
|
88
|
+
<button id="sidebarMetricsBtn" class="btn-secondary"
|
|
89
|
+
style="width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 12px; padding: 8px 12px; border-radius: var(--r-sm); font-size: 0.8rem; background: var(--bg-elevated); border: 1px solid var(--border-mid); color: var(--text-primary); cursor: pointer; transition: all 0.2s;"><i
|
|
90
|
+
data-lucide="bar-chart-2" style="width: 14px; height: 14px;"></i> Performance Metrics</button>
|
|
91
|
+
<button id="sidebarSettingsBtn" class="btn-secondary"
|
|
92
|
+
style="width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px; margin-bottom: 12px; padding: 8px 12px; border-radius: var(--r-sm); font-size: 0.8rem; background: var(--bg-elevated); border: 1px solid var(--border-mid); color: var(--text-primary); cursor: pointer; transition: all 0.2s;"><i
|
|
93
|
+
data-lucide="settings" style="width: 14px; height: 14px;"></i> Settings</button>
|
|
94
|
+
<span>Crewlyze v3.1</span>
|
|
95
|
+
</div>
|
|
96
|
+
</aside>
|
|
97
|
+
|
|
98
|
+
<!-- ═══════════════════════════════ MAIN AREA ═════════════════════════════════ -->
|
|
99
|
+
<main class="main-area">
|
|
100
|
+
|
|
101
|
+
<!-- TOP NAV -->
|
|
102
|
+
<header class="topbar">
|
|
103
|
+
<div class="topbar-left">
|
|
104
|
+
<button id="mobileSidebarBtn" class="btn-icon-lg">☰</button>
|
|
105
|
+
<div id="breadcrumb" class="breadcrumb">
|
|
106
|
+
<span class="breadcrumb-item active">Dashboard</span>
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
<div class="topbar-right">
|
|
110
|
+
<div id="statusPill" class="status-pill idle">● Idle</div>
|
|
111
|
+
</div>
|
|
112
|
+
</header>
|
|
113
|
+
|
|
114
|
+
<!-- ─── LANDING / UPLOAD SCREEN ─── -->
|
|
115
|
+
<section id="landingScreen" class="screen active">
|
|
116
|
+
<div class="landing-hero">
|
|
117
|
+
<div class="hero-badge">✦ Powered by CrewAI Multi-Agent Pipeline</div>
|
|
118
|
+
<h1 class="hero-title"><span class="gradient-text">Crewlyze</span></h1>
|
|
119
|
+
<p class="hero-subtitle">Upload a CSV and let autonomous AI agents clean your data, discover relationships,
|
|
120
|
+
surface strategic insights, and generate interactive visualizations — all in one pipeline.</p>
|
|
121
|
+
|
|
122
|
+
<!-- Wizard Container -->
|
|
123
|
+
<div class="wizard-container" id="newProjectWizard">
|
|
124
|
+
<!-- Step 0: Create Project Button Card -->
|
|
125
|
+
<div class="wizard-step active" id="wizardStep0"
|
|
126
|
+
style="width: 100%; display: flex; flex-direction: row !important; justify-content: center; gap: 20px; flex-wrap: wrap;">
|
|
127
|
+
<div class="create-project-card" id="startWizardCard">
|
|
128
|
+
<div class="create-project-plus">+</div>
|
|
129
|
+
<div class="create-project-text">Create New Project</div>
|
|
130
|
+
<div class="create-project-desc"
|
|
131
|
+
style="font-size: 0.75rem; color: var(--text-secondary); margin-top: 8px; text-align: center; max-width: 200px;">
|
|
132
|
+
Start a fresh analysis pipeline with a new CSV dataset</div>
|
|
133
|
+
</div>
|
|
134
|
+
<div class="create-project-card" id="importProjectCard"
|
|
135
|
+
style="background: rgba(16,185,129,0.02); border-color: rgba(16,185,129,0.2);">
|
|
136
|
+
<div class="create-project-plus" style="color: #10b981;">↓</div>
|
|
137
|
+
<div class="create-project-text" style="color: var(--text-primary);">Import Project (.zip)</div>
|
|
138
|
+
<div class="create-project-desc"
|
|
139
|
+
style="font-size: 0.75rem; color: var(--text-secondary); margin-top: 8px; text-align: center; max-width: 200px;">
|
|
140
|
+
Load and restore an existing project session from backup</div>
|
|
141
|
+
<input type="file" id="importZipFileInput" accept=".zip" style="display: none;" />
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
<!-- Step 1: Project Name -->
|
|
146
|
+
<div class="wizard-step" id="wizardStep1">
|
|
147
|
+
<button id="wizardBack1Btn" class="btn-back">← Back</button>
|
|
148
|
+
<div class="wizard-icon"><i data-lucide="sparkles"
|
|
149
|
+
style="width: 32px; height: 32px; color: var(--violet-light);"></i></div>
|
|
150
|
+
<h3 class="wizard-step-title">Create New Project</h3>
|
|
151
|
+
<p class="wizard-step-desc">Enter a name, and optionally a title and goal for your project.</p>
|
|
152
|
+
<div
|
|
153
|
+
style="width: 100%; max-width: 440px; margin: 16px auto 0; text-align: left; display: flex; flex-direction: column; gap: 12px;">
|
|
154
|
+
<div class="field-group">
|
|
155
|
+
<label class="field-label" style="font-weight: 600; margin-bottom: 4px;">Project Name</label>
|
|
156
|
+
<input type="text" id="wizardProjectName" class="field-input" placeholder="e.g. Sales Analysis Q3"
|
|
157
|
+
style="font-size: 0.95rem; padding: 10px 12px; width: 100%; box-sizing: border-box;" />
|
|
158
|
+
</div>
|
|
159
|
+
<div class="field-group">
|
|
160
|
+
<label class="field-label" style="font-weight: 600; margin-bottom: 4px;">Report Title (Optional)</label>
|
|
161
|
+
<input type="text" id="wizardReportTitle" class="field-input"
|
|
162
|
+
placeholder="e.g. Q3 Sales Executive Analysis"
|
|
163
|
+
style="font-size: 0.95rem; padding: 10px 12px; width: 100%; box-sizing: border-box;" />
|
|
164
|
+
</div>
|
|
165
|
+
<div class="field-group">
|
|
166
|
+
<label class="field-label" style="font-weight: 600; margin-bottom: 4px;">Project Goal / Objective
|
|
167
|
+
(Optional)</label>
|
|
168
|
+
<textarea id="wizardProjectGoal" class="field-input" rows="3"
|
|
169
|
+
placeholder="e.g. Identify top 10% highest-margin customer segments and explain why spend exceeded budget."
|
|
170
|
+
style="font-size: 0.95rem; padding: 10px 12px; font-family: inherit; resize: none; width: 100%; box-sizing: border-box;"></textarea>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
<button id="wizardNextBtn" class="btn-primary btn-lg mt-20"
|
|
174
|
+
style="min-width: 200px; margin-top: 20px;">Continue to Upload →</button>
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
<!-- Step 2: Upload CSV -->
|
|
178
|
+
<div class="wizard-step" id="wizardStep2">
|
|
179
|
+
<button id="wizardBackBtn" class="btn-back">← Back</button>
|
|
180
|
+
<div class="wizard-icon"><i data-lucide="folder-open"
|
|
181
|
+
style="width: 32px; height: 32px; color: var(--violet-light);"></i></div>
|
|
182
|
+
<h3 class="wizard-step-title" id="wizardUploadTitle">Upload CSV Dataset</h3>
|
|
183
|
+
<p class="wizard-step-desc">Select or drop the CSV file you want the agents to analyze.</p>
|
|
184
|
+
|
|
185
|
+
<div class="upload-zone" id="uploadZone"
|
|
186
|
+
style="width: 100%; max-width: 520px; margin: 20px auto 0; background: rgba(124,58,237,0.02);">
|
|
187
|
+
<div class="upload-icon"><i data-lucide="file"
|
|
188
|
+
style="width: 32px; height: 32px; color: var(--violet-light);"></i></div>
|
|
189
|
+
<div class="upload-title">Drop your CSV here</div>
|
|
190
|
+
<div class="upload-hint">or <label for="fileInput" class="upload-link">browse files</label></div>
|
|
191
|
+
<input type="file" id="fileInput" accept=".csv" hidden />
|
|
192
|
+
<div id="uploadedFileMeta" class="upload-meta hidden"></div>
|
|
193
|
+
</div>
|
|
194
|
+
|
|
195
|
+
<div id="uploadedFileActions" class="upload-actions hidden" style="margin-top: 20px;">
|
|
196
|
+
<button id="startAnalysisBtn" class="btn-primary btn-lg"><i data-lucide="play"
|
|
197
|
+
style="width: 16px; height: 16px; fill: currentColor; vertical-align: middle; margin-right: 6px;"></i>
|
|
198
|
+
Configure & Run Analysis</button>
|
|
199
|
+
</div>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
|
|
204
|
+
<!-- Projects Section -->
|
|
205
|
+
<div class="dashboard-projects-section">
|
|
206
|
+
<div class="section-title-row">
|
|
207
|
+
<h2 class="section-title">Recent Projects</h2>
|
|
208
|
+
<span class="projects-count" id="dashboardProjectsCount">(0)</span>
|
|
209
|
+
</div>
|
|
210
|
+
<div class="projects-grid" id="dashboardProjectsGrid">
|
|
211
|
+
<!-- Rendered dynamically via app.js -->
|
|
212
|
+
</div>
|
|
213
|
+
</div>
|
|
214
|
+
</section>
|
|
215
|
+
|
|
216
|
+
<!-- ─── ANALYSIS CONFIG MODAL ─── -->
|
|
217
|
+
<div id="configModal" class="modal-overlay hidden">
|
|
218
|
+
<div class="modal-box">
|
|
219
|
+
<div class="modal-header">
|
|
220
|
+
<h2><i data-lucide="settings"
|
|
221
|
+
style="width: 20px; height: 20px; vertical-align: middle; margin-right: 6px;"></i> Analysis Configuration
|
|
222
|
+
</h2>
|
|
223
|
+
<button id="closeConfigModal" class="btn-icon">✕</button>
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
<div class="modal-body">
|
|
227
|
+
<p class="modal-hint">Select which stages to run. Dependencies are enforced automatically.</p>
|
|
228
|
+
|
|
229
|
+
<!-- Task cards -->
|
|
230
|
+
<div class="task-grid" id="taskGrid">
|
|
231
|
+
<label class="task-card" id="taskCardCleaning">
|
|
232
|
+
<input type="checkbox" id="taskCleaning" value="cleaning" checked />
|
|
233
|
+
<div class="task-card-icon"><i data-lucide="brush"
|
|
234
|
+
style="width: 20px; height: 20px; color: var(--violet-light);"></i></div>
|
|
235
|
+
<div class="task-card-body">
|
|
236
|
+
<div class="task-card-title">Data Cleaning</div>
|
|
237
|
+
<div class="task-card-desc">Fix quality issues: missing values, types, duplicates.</div>
|
|
238
|
+
</div>
|
|
239
|
+
<div class="task-card-check"><i data-lucide="check" style="width: 14px; height: 14px;"></i></div>
|
|
240
|
+
</label>
|
|
241
|
+
|
|
242
|
+
<label class="task-card" id="taskCardRelations">
|
|
243
|
+
<input type="checkbox" id="taskRelations" value="relations" checked />
|
|
244
|
+
<div class="task-card-icon"><i data-lucide="link"
|
|
245
|
+
style="width: 20px; height: 20px; color: var(--cyan);"></i></div>
|
|
246
|
+
<div class="task-card-body">
|
|
247
|
+
<div class="task-card-title">Relationship Analysis</div>
|
|
248
|
+
<div class="task-card-desc">Discover correlations & patterns. <em>Requires Cleaning.</em></div>
|
|
249
|
+
</div>
|
|
250
|
+
<div class="task-card-check"><i data-lucide="check" style="width: 14px; height: 14px;"></i></div>
|
|
251
|
+
</label>
|
|
252
|
+
|
|
253
|
+
<label class="task-card" id="taskCardInsights">
|
|
254
|
+
<input type="checkbox" id="taskInsights" value="insights" checked />
|
|
255
|
+
<div class="task-card-icon"><i data-lucide="lightbulb"
|
|
256
|
+
style="width: 20px; height: 20px; color: var(--amber);"></i></div>
|
|
257
|
+
<div class="task-card-body">
|
|
258
|
+
<div class="task-card-title">Business Insights</div>
|
|
259
|
+
<div class="task-card-desc">Strategic recommendations. <em>Requires Cleaning.</em></div>
|
|
260
|
+
</div>
|
|
261
|
+
<div class="task-card-check"><i data-lucide="check" style="width: 14px; height: 14px;"></i></div>
|
|
262
|
+
</label>
|
|
263
|
+
|
|
264
|
+
<label class="task-card" id="taskCardViz">
|
|
265
|
+
<input type="checkbox" id="taskViz" value="visualization" checked />
|
|
266
|
+
<div class="task-card-icon"><i data-lucide="trending-up"
|
|
267
|
+
style="width: 20px; height: 20px; color: var(--rose);"></i></div>
|
|
268
|
+
<div class="task-card-body">
|
|
269
|
+
<div class="task-card-title">Visualization</div>
|
|
270
|
+
<div class="task-card-desc">Interactive charts & PNGs. <em>Requires Relations.</em></div>
|
|
271
|
+
</div>
|
|
272
|
+
<div class="task-card-check"><i data-lucide="check" style="width: 14px; height: 14px;"></i></div>
|
|
273
|
+
</label>
|
|
274
|
+
</div>
|
|
275
|
+
|
|
276
|
+
<!-- Analysis depth -->
|
|
277
|
+
<div class="depth-selector">
|
|
278
|
+
<div class="depth-label"><i data-lucide="search"
|
|
279
|
+
style="width: 14px; height: 14px; vertical-align: middle; margin-right: 4px;"></i> Analysis Depth</div>
|
|
280
|
+
<div class="depth-options">
|
|
281
|
+
<label class="depth-option active" id="depthStandard">
|
|
282
|
+
<input type="radio" name="depth" value="false" checked />
|
|
283
|
+
<span class="depth-icon"><i data-lucide="zap"
|
|
284
|
+
style="width: 14px; height: 14px; color: var(--violet-light);"></i></span>
|
|
285
|
+
<span class="depth-name">Standard</span>
|
|
286
|
+
<span class="depth-desc">Faster, concise</span>
|
|
287
|
+
</label>
|
|
288
|
+
<label class="depth-option" id="depthDeep">
|
|
289
|
+
<input type="radio" name="depth" value="true" />
|
|
290
|
+
<span class="depth-icon"><i data-lucide="microscope"
|
|
291
|
+
style="width: 14px; height: 14px; color: var(--cyan);"></i></span>
|
|
292
|
+
<span class="depth-name">Deep</span>
|
|
293
|
+
<span class="depth-desc">Richer analysis & detail</span>
|
|
294
|
+
</label>
|
|
295
|
+
</div>
|
|
296
|
+
</div>
|
|
297
|
+
|
|
298
|
+
<!-- Report title -->
|
|
299
|
+
<div class="field-group">
|
|
300
|
+
<label class="field-label">Report Title</label>
|
|
301
|
+
<input type="text" id="reportTitle" class="field-input"
|
|
302
|
+
placeholder="e.g. Q4 2024 Sales Performance Analysis" />
|
|
303
|
+
</div>
|
|
304
|
+
</div>
|
|
305
|
+
|
|
306
|
+
<div class="modal-footer">
|
|
307
|
+
<button id="cancelConfigBtn" class="btn-secondary">Cancel</button>
|
|
308
|
+
<button id="runAnalysisBtn" class="btn-primary"><i data-lucide="play"
|
|
309
|
+
style="width: 14px; height: 14px; fill: currentColor; vertical-align: middle; margin-right: 4px;"></i>
|
|
310
|
+
Start Analysis</button>
|
|
311
|
+
</div>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
|
|
315
|
+
<!-- ─── ANALYSIS RUNNING SCREEN ─── -->
|
|
316
|
+
<section id="runningScreen" class="screen">
|
|
317
|
+
<div class="running-header" style="display: flex; align-items: center; width: 100%;">
|
|
318
|
+
<div class="running-spinner"></div>
|
|
319
|
+
<div style="flex: 1;">
|
|
320
|
+
<h2 id="runningTitle">Agents are Analysing Your Data…</h2>
|
|
321
|
+
<p class="running-sub">This may take 2–10 minutes depending on dataset size and LLM speed.</p>
|
|
322
|
+
</div>
|
|
323
|
+
<button id="btnRunInBackground" class="btn-secondary btn-sm"
|
|
324
|
+
style="margin-left: auto; display: flex; align-items: center; gap: 6px;"><i data-lucide="minimize-2"
|
|
325
|
+
style="width: 14px; height: 14px;"></i> Run in Background</button>
|
|
326
|
+
</div>
|
|
327
|
+
|
|
328
|
+
<!-- Stage progress -->
|
|
329
|
+
<div class="stages-track">
|
|
330
|
+
<div class="stage-item" data-stage="cleaning">
|
|
331
|
+
<div class="stage-dot"></div>
|
|
332
|
+
<div class="stage-label">Cleaning</div>
|
|
333
|
+
</div>
|
|
334
|
+
<div class="stage-item" data-stage="relations">
|
|
335
|
+
<div class="stage-dot"></div>
|
|
336
|
+
<div class="stage-label">Relations</div>
|
|
337
|
+
</div>
|
|
338
|
+
<div class="stage-item" data-stage="insights">
|
|
339
|
+
<div class="stage-dot"></div>
|
|
340
|
+
<div class="stage-label">Insights</div>
|
|
341
|
+
</div>
|
|
342
|
+
<div class="stage-item" data-stage="visualization">
|
|
343
|
+
<div class="stage-dot"></div>
|
|
344
|
+
<div class="stage-label">Visualization</div>
|
|
345
|
+
</div>
|
|
346
|
+
<div class="stage-item" data-stage="plotly">
|
|
347
|
+
<div class="stage-dot"></div>
|
|
348
|
+
<div class="stage-label">Charts</div>
|
|
349
|
+
</div>
|
|
350
|
+
</div>
|
|
351
|
+
|
|
352
|
+
<!-- Dynamic Stage POV Panel -->
|
|
353
|
+
<div id="stagePovPanel" class="stage-pov-panel">
|
|
354
|
+
<div class="pov-initial-state">
|
|
355
|
+
<div class="pov-pulse-ring"></div>
|
|
356
|
+
<p>Awaiting analysis stream...</p>
|
|
357
|
+
</div>
|
|
358
|
+
</div>
|
|
359
|
+
|
|
360
|
+
<!-- Live log -->
|
|
361
|
+
<div class="log-panel">
|
|
362
|
+
<div class="log-header">
|
|
363
|
+
<span><i data-lucide="clipboard-list"
|
|
364
|
+
style="width: 16px; height: 16px; vertical-align: middle; margin-right: 6px;"></i> Live Agent Log</span>
|
|
365
|
+
<button id="clearLogBtn" class="btn-xs">Clear</button>
|
|
366
|
+
</div>
|
|
367
|
+
<div id="logOutput" class="log-output"></div>
|
|
368
|
+
</div>
|
|
369
|
+
</section>
|
|
370
|
+
|
|
371
|
+
<!-- ─── RESULTS DASHBOARD SCREEN ─── -->
|
|
372
|
+
<section id="resultsScreen" class="screen">
|
|
373
|
+
|
|
374
|
+
<!-- Stat row -->
|
|
375
|
+
<div class="stats-row" id="statsRow" style="margin-bottom: 20px;"></div>
|
|
376
|
+
|
|
377
|
+
<!-- Main Sections Switch -->
|
|
378
|
+
<div class="sections-switch" style="display: none !important;">
|
|
379
|
+
<button class="section-switch-btn active" id="btnSectionChat"
|
|
380
|
+
style="flex: 1; padding: 10px 20px; border: none; background: var(--violet-dark); color: #fff; font-weight: 600; border-radius: 26px; cursor: pointer; transition: all 0.3s; display: flex; align-items: center; justify-content: center; gap: 8px;"><i
|
|
381
|
+
data-lucide="message-square" style="width: 16px; height: 16px;"></i> AI Data Chat</button>
|
|
382
|
+
<button class="section-switch-btn" id="btnSectionAgentic"
|
|
383
|
+
style="flex: 1; padding: 10px 20px; border: none; background: transparent; color: var(--text-secondary); font-weight: 600; border-radius: 26px; cursor: pointer; transition: all 0.3s; display: flex; align-items: center; justify-content: center; gap: 8px;"><i
|
|
384
|
+
data-lucide="bot" style="width: 16px; height: 16px;"></i> Agentic Analysis</button>
|
|
385
|
+
</div>
|
|
386
|
+
|
|
387
|
+
<!-- ───────────────── SECTION 0: WORKSPACE HUB (SELECT MODE) ───────────────── -->
|
|
388
|
+
<div id="areaHub" class="section-area active">
|
|
389
|
+
<div
|
|
390
|
+
style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px 20px; text-align: center; max-width: 800px; margin: 0 auto; gap: 32px;">
|
|
391
|
+
<div>
|
|
392
|
+
<h2 style="font-size: 1.8rem; font-weight: 700; margin: 0 0 10px 0; color: #fff;">Choose Your Workspace Mode
|
|
393
|
+
</h2>
|
|
394
|
+
<p
|
|
395
|
+
style="color: var(--text-secondary); max-width: 540px; margin: 0 auto; font-size: 0.95rem; line-height: 1.5;">
|
|
396
|
+
Select how you would like to interact with the project dataset. Switch modes at any time.
|
|
397
|
+
</p>
|
|
398
|
+
</div>
|
|
399
|
+
|
|
400
|
+
<div class="hub-cards-grid"
|
|
401
|
+
style="display: flex; gap: 24px; width: 100%; justify-content: center; flex-wrap: wrap; margin-top: 10px;">
|
|
402
|
+
<!-- Card 1: AI Chat -->
|
|
403
|
+
<div class="hub-card" id="btnEnterChat"
|
|
404
|
+
style="flex: 1; min-width: 280px; max-width: 360px; background: var(--bg-elevated); border: 1px solid var(--border-mid); border-radius: var(--r-lg); padding: 32px 24px; text-align: center; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); display: flex; flex-direction: column; align-items: center; gap: 16px;">
|
|
405
|
+
<div class="hub-card-icon-wrap"
|
|
406
|
+
style="width: 64px; height: 64px; border-radius: 50%; background: rgba(167, 139, 250, 0.1); display: flex; align-items: center; justify-content: center;">
|
|
407
|
+
<i data-lucide="message-square" style="width: 32px; height: 32px; color: var(--violet-light);"></i>
|
|
408
|
+
</div>
|
|
409
|
+
<h3 style="margin: 0; font-size: 1.3rem; font-weight: 700; color: #fff;">AI Data Chat</h3>
|
|
410
|
+
<p style="color: var(--text-secondary); font-size: 0.85rem; line-height: 1.5; margin: 0; flex: 1;">
|
|
411
|
+
Ask questions, query statistical metrics, run quick data edits, and request tailored interactive
|
|
412
|
+
visualizations in a conversational interface.
|
|
413
|
+
</p>
|
|
414
|
+
<button class="btn-primary"
|
|
415
|
+
style="display: inline-flex; justify-content: center; align-items: center; text-align: center; pointer-events: none; width: 100%; padding: 10px 0; font-size: 0.85rem; font-weight: 700; background: var(--violet); color: #fff; border: none; transition: transform 0.2s;">Open
|
|
416
|
+
Chat Workspace</button>
|
|
417
|
+
</div>
|
|
418
|
+
|
|
419
|
+
<!-- Card 2: Crew Analysis -->
|
|
420
|
+
<div class="hub-card" id="btnEnterAgentic"
|
|
421
|
+
style="flex: 1; min-width: 280px; max-width: 360px; background: var(--bg-elevated); border: 1px solid var(--border-mid); border-radius: var(--r-lg); padding: 32px 24px; text-align: center; cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); display: flex; flex-direction: column; align-items: center; gap: 16px;">
|
|
422
|
+
<div class="hub-card-icon-wrap"
|
|
423
|
+
style="width: 64px; height: 64px; border-radius: 50%; background: rgba(6, 182, 212, 0.1); display: flex; align-items: center; justify-content: center;">
|
|
424
|
+
<i data-lucide="bot" style="width: 32px; height: 32px; color: var(--cyan);"></i>
|
|
425
|
+
</div>
|
|
426
|
+
<h3 style="margin: 0; font-size: 1.3rem; font-weight: 700; color: #fff;">Crew Agentic Analysis</h3>
|
|
427
|
+
<p style="color: var(--text-secondary); font-size: 0.85rem; line-height: 1.5; margin: 0; flex: 1;">
|
|
428
|
+
Trigger structured multi-agent pipelines to clean datasets, map schema relationships, generate
|
|
429
|
+
McKinsey-style recommendations, and build dashboard suites.
|
|
430
|
+
</p>
|
|
431
|
+
<button class="btn-primary"
|
|
432
|
+
style="display: inline-flex; justify-content: center; align-items: center; text-align: center; pointer-events: none; width: 100%; padding: 10px 0; font-size: 0.85rem; font-weight: 700; background: var(--cyan); color: var(--bg-dark); border: none; transition: transform 0.2s;">Open
|
|
433
|
+
Agent Workspace</button>
|
|
434
|
+
</div>
|
|
435
|
+
</div>
|
|
436
|
+
</div>
|
|
437
|
+
</div>
|
|
438
|
+
|
|
439
|
+
<!-- ───────────────── SECTION 1: AI DATA CHAT ───────────────── -->
|
|
440
|
+
<div id="areaChat" class="section-area hidden">
|
|
441
|
+
<div style="display: flex; flex-direction: column; gap: 20px;">
|
|
442
|
+
|
|
443
|
+
<!-- Table Preview Area -->
|
|
444
|
+
<div id="datasetExplorerCard" class="card"
|
|
445
|
+
style="padding: 18px; background: var(--bg-elevated); border: 1px solid var(--border-mid);">
|
|
446
|
+
<div
|
|
447
|
+
style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px; flex-wrap: wrap; gap: 8px;">
|
|
448
|
+
<h3 style="margin: 0; font-size: 1.1rem; display: flex; align-items: center; gap: 8px;"><i
|
|
449
|
+
data-lucide="search" style="width: 18px; height: 18px; color: var(--violet-light);"></i> Dataset
|
|
450
|
+
Explorer <span id="chatPreviewDims"
|
|
451
|
+
style="font-size: 0.75rem; font-weight: normal; color: var(--text-secondary);"></span></h3>
|
|
452
|
+
<div style="display: flex; gap: 8px;">
|
|
453
|
+
<button id="btnRenameColQuick" class="btn-secondary btn-sm"
|
|
454
|
+
style="font-size: 0.75rem; display: flex; align-items: center; gap: 4px;"><i data-lucide="edit"
|
|
455
|
+
style="width: 12px; height: 12px;"></i> Rename Column</button>
|
|
456
|
+
<button id="btnDeleteColQuick" class="btn-secondary btn-sm"
|
|
457
|
+
style="font-size: 0.75rem; border-color: rgba(239, 68, 68, 0.2); color: #ef4444; display: flex; align-items: center; gap: 4px;"><i
|
|
458
|
+
data-lucide="trash-2" style="width: 12px; height: 12px;"></i> Delete Column</button>
|
|
459
|
+
</div>
|
|
460
|
+
</div>
|
|
461
|
+
<div id="previewTableWrap" class="table-wrap" style="max-height: 250px; overflow-y: auto;">
|
|
462
|
+
<div id="previewTable" class="data-table-container"></div>
|
|
463
|
+
</div>
|
|
464
|
+
</div>
|
|
465
|
+
|
|
466
|
+
<!-- Chat Container -->
|
|
467
|
+
<div id="chatContainerCard" class="card"
|
|
468
|
+
style="padding: 20px; background: var(--bg-elevated); border: 1px solid var(--border-mid); display: flex; flex-direction: column; min-height: 480px;">
|
|
469
|
+
<div
|
|
470
|
+
style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; border-bottom: 1px solid var(--border-low); padding-bottom: 12px;">
|
|
471
|
+
<div style="display: flex; align-items: center; gap: 12px;">
|
|
472
|
+
<button id="chatBackBtn" class="btn-icon"
|
|
473
|
+
style="background:var(--bg-elevated); border:1px solid var(--border-mid); border-radius:var(--r-md); padding:10px; cursor:pointer; color:var(--text-primary);"
|
|
474
|
+
title="Back to Dashboard"><i data-lucide="arrow-left" style="width:20px; height:20px;"></i></button>
|
|
475
|
+
<h3 style="margin: 0; font-size: 1.1rem; display: flex; align-items: center; gap: 8px;"><i
|
|
476
|
+
data-lucide="message-square" style="width: 18px; height: 18px; color: var(--violet-light);"></i> AI
|
|
477
|
+
Copilot</h3>
|
|
478
|
+
</div>
|
|
479
|
+
<button id="clearChatBtn" class="btn-secondary btn-sm">Clear Conversation</button>
|
|
480
|
+
</div>
|
|
481
|
+
|
|
482
|
+
<div id="chatMessages" class="chat-messages"
|
|
483
|
+
style="flex: 1; min-height: 260px; overflow-y: auto; padding-right: 4px; display: flex; flex-direction: column; gap: 16px; margin-bottom: 16px;">
|
|
484
|
+
<!-- messages populate here -->
|
|
485
|
+
</div>
|
|
486
|
+
|
|
487
|
+
<div class="chat-input-area" style="position: relative;">
|
|
488
|
+
<div id="colPickerDropdown" class="col-picker-dropdown hidden"
|
|
489
|
+
style="position: absolute; bottom: 100%; left: 0; right: 0; background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--r-md); z-index: 10; max-height: 160px; overflow-y: auto; padding: 4px;">
|
|
490
|
+
</div>
|
|
491
|
+
<div class="chat-input-row" style="display: flex; gap: 8px; align-items: flex-end;">
|
|
492
|
+
<textarea id="chatInput" class="chat-textarea" rows="2"
|
|
493
|
+
placeholder="Ask questions, request visual charts, or modify columns (type / to select a column)..."
|
|
494
|
+
style="flex: 1; background: var(--bg-card); color: var(--text-primary); border: 1px solid var(--border-mid); border-radius: var(--r-md); padding: 10px 14px; font-size: 0.9rem; font-family: inherit; resize: none;"></textarea>
|
|
495
|
+
<button id="sendChatBtn" class="btn-primary btn-send"
|
|
496
|
+
style="padding: 12px 20px; border-radius: var(--r-md); font-weight: 600;">Send ↑</button>
|
|
497
|
+
</div>
|
|
498
|
+
<div class="chat-hints"
|
|
499
|
+
style="display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; font-size: 0.75rem; color: var(--text-secondary);">
|
|
500
|
+
<span class="chat-hint-chip" data-query="Show summary statistics for all numeric columns"
|
|
501
|
+
style="background: var(--bg-card); border: 1px solid var(--border-low); padding: 4px 10px; border-radius: 12px; cursor: pointer; transition: all 0.2s;"><i
|
|
502
|
+
data-lucide="bar-chart-2"
|
|
503
|
+
style="width: 12px; height: 12px; vertical-align: middle; margin-right: 4px;"></i> Summary
|
|
504
|
+
Stats</span>
|
|
505
|
+
<span class="chat-hint-chip"
|
|
506
|
+
data-query="Plot a distribution histogram of the first column with custom color config"
|
|
507
|
+
style="background: var(--bg-card); border: 1px solid var(--border-low); padding: 4px 10px; border-radius: 12px; cursor: pointer; transition: all 0.2s;"><i
|
|
508
|
+
data-lucide="trending-down"
|
|
509
|
+
style="width: 12px; height: 12px; vertical-align: middle; margin-right: 4px;"></i> Custom
|
|
510
|
+
Histogram</span>
|
|
511
|
+
<span class="chat-hint-chip" data-query="Rename column..."
|
|
512
|
+
style="background: var(--bg-card); border: 1px solid var(--border-low); padding: 4px 10px; border-radius: 12px; cursor: pointer; transition: all 0.2s;"><i
|
|
513
|
+
data-lucide="edit"
|
|
514
|
+
style="width: 12px; height: 12px; vertical-align: middle; margin-right: 4px;"></i> Rename
|
|
515
|
+
Column</span>
|
|
516
|
+
<span class="chat-hint-chip" data-query="Delete column..."
|
|
517
|
+
style="background: var(--bg-card); border: 1px solid var(--border-low); padding: 4px 10px; border-radius: 12px; cursor: pointer; transition: all 0.2s;"><i
|
|
518
|
+
data-lucide="trash-2"
|
|
519
|
+
style="width: 12px; height: 12px; vertical-align: middle; margin-right: 4px;"></i> Delete
|
|
520
|
+
Column</span>
|
|
521
|
+
</div>
|
|
522
|
+
</div>
|
|
523
|
+
</div>
|
|
524
|
+
|
|
525
|
+
</div>
|
|
526
|
+
</div>
|
|
527
|
+
|
|
528
|
+
<!-- ───────────────── SECTION 2: AGENTIC ANALYSIS ───────────────── -->
|
|
529
|
+
<div id="areaAgentic" class="section-area hidden">
|
|
530
|
+
<!-- Run Analysis Placeholder -->
|
|
531
|
+
<div id="agenticPlaceholder" class="hidden"
|
|
532
|
+
style="text-align: center; padding: 60px 20px; background: rgba(24, 24, 27, 0.4); border: 1px dashed var(--border-mid); border-radius: var(--r-lg); max-width: 580px; margin: 40px auto; display: flex; flex-direction: column; align-items: center; gap: 16px; backdrop-filter: blur(12px);">
|
|
533
|
+
<div style="font-size: 3rem; animation: pulse 2s infinite;"><i data-lucide="bot"
|
|
534
|
+
style="width: 48px; height: 48px; color: var(--violet-light);"></i></div>
|
|
535
|
+
<h3 style="margin: 0; font-size: 1.2rem; font-weight: 700; color: #fff;">Automated Pipeline Analysis</h3>
|
|
536
|
+
<p style="color: var(--text-secondary); line-height: 1.5; margin: 0; font-size: 0.9rem;">
|
|
537
|
+
Trigger autonomous AI agents to perform data cleaning, schema relationship mapping, and surface
|
|
538
|
+
consulting-grade insights.
|
|
539
|
+
</p>
|
|
540
|
+
<button id="btnRunAgenticPipeline" class="btn-primary btn-lg" style="margin-top: 10px; font-weight: 600;"><i
|
|
541
|
+
data-lucide="play"
|
|
542
|
+
style="width: 16px; height: 16px; fill: currentColor; vertical-align: middle; margin-right: 6px;"></i>
|
|
543
|
+
Configure & Run Analysis</button>
|
|
544
|
+
</div>
|
|
545
|
+
|
|
546
|
+
<!-- Tabs -->
|
|
547
|
+
<div class="tabs-bar" id="agenticTabsBar" style="margin-bottom: 16px;">
|
|
548
|
+
<button class="tab-btn active" data-tab="cleaning"><i data-lucide="brush"
|
|
549
|
+
style="width: 14px; height: 14px; vertical-align: middle; margin-right: 4px;"></i> Cleaning
|
|
550
|
+
Report</button>
|
|
551
|
+
<button class="tab-btn" data-tab="relations"><i data-lucide="link"
|
|
552
|
+
style="width: 14px; height: 14px; vertical-align: middle; margin-right: 4px;"></i> Relation
|
|
553
|
+
Mapper</button>
|
|
554
|
+
<button class="tab-btn" data-tab="insights"><i data-lucide="lightbulb"
|
|
555
|
+
style="width: 14px; height: 14px; vertical-align: middle; margin-right: 4px;"></i> Business
|
|
556
|
+
Insights</button>
|
|
557
|
+
<button class="tab-btn" data-tab="charts"><i data-lucide="trending-up"
|
|
558
|
+
style="width: 14px; height: 14px; vertical-align: middle; margin-right: 4px;"></i> Visualizations</button>
|
|
559
|
+
</div>
|
|
560
|
+
|
|
561
|
+
<!-- Tab panels -->
|
|
562
|
+
<div class="tab-panels" id="agenticTabPanels">
|
|
563
|
+
<!-- CLEANING REPORT -->
|
|
564
|
+
<div class="tab-panel active" id="panel-cleaning">
|
|
565
|
+
<h3 class="panel-title"><i data-lucide="brush"
|
|
566
|
+
style="width: 18px; height: 18px; vertical-align: middle; margin-right: 6px;"></i> Data Cleaning Audit
|
|
567
|
+
Trail</h3>
|
|
568
|
+
<div id="cleaningContent" class="cleaning-list"></div>
|
|
569
|
+
</div>
|
|
570
|
+
|
|
571
|
+
<!-- RELATIONS -->
|
|
572
|
+
<div class="tab-panel" id="panel-relations">
|
|
573
|
+
<h3 class="panel-title"><i data-lucide="link"
|
|
574
|
+
style="width: 18px; height: 18px; vertical-align: middle; margin-right: 6px;"></i> Relationship Mapping
|
|
575
|
+
</h3>
|
|
576
|
+
<div id="relationsContent" style="width: 100%;"></div>
|
|
577
|
+
</div>
|
|
578
|
+
|
|
579
|
+
<!-- INSIGHTS -->
|
|
580
|
+
<div class="tab-panel" id="panel-insights">
|
|
581
|
+
<h3 class="panel-title"><i data-lucide="lightbulb"
|
|
582
|
+
style="width: 18px; height: 18px; vertical-align: middle; margin-right: 6px;"></i> Strategic Business
|
|
583
|
+
Insights</h3>
|
|
584
|
+
<div id="insightsContent" class="insights-list"></div>
|
|
585
|
+
</div>
|
|
586
|
+
|
|
587
|
+
<!-- CHARTS -->
|
|
588
|
+
<div class="tab-panel" id="panel-charts">
|
|
589
|
+
<h3 class="panel-title"><i data-lucide="trending-up"
|
|
590
|
+
style="width: 18px; height: 18px; vertical-align: middle; margin-right: 6px;"></i> Visual Intelligence
|
|
591
|
+
</h3>
|
|
592
|
+
<div id="plotlyChartsWrap" class="charts-grid"></div>
|
|
593
|
+
<div id="pngChartsWrap" class="png-charts-wrap hidden">
|
|
594
|
+
<h4 class="sub-title"><i data-lucide="image"
|
|
595
|
+
style="width: 16px; height: 16px; vertical-align: middle; margin-right: 6px;"></i> Agent-Generated
|
|
596
|
+
Charts</h4>
|
|
597
|
+
<div id="pngCharts" class="png-grid"></div>
|
|
598
|
+
</div>
|
|
599
|
+
<details class="viz-code-details hidden" id="vizCodeDetails">
|
|
600
|
+
<summary><i data-lucide="code"
|
|
601
|
+
style="width: 16px; height: 16px; vertical-align: middle; margin-right: 6px;"></i> Visualization
|
|
602
|
+
Architecture Code</summary>
|
|
603
|
+
<pre id="vizCodeBlock" class="code-block"></pre>
|
|
604
|
+
</details>
|
|
605
|
+
</div>
|
|
606
|
+
</div>
|
|
607
|
+
</div>
|
|
608
|
+
|
|
609
|
+
<!-- Export/action bar -->
|
|
610
|
+
<div class="export-bar" style="margin-top: 24px;">
|
|
611
|
+
<button id="exportPdfBtn" class="btn-primary"><i data-lucide="file-text" style="width: 14px; height: 14px;"></i>
|
|
612
|
+
Export PDF Report</button>
|
|
613
|
+
<button id="exportZipBtn" class="btn-secondary"
|
|
614
|
+
style="background: rgba(124,58,237,0.06); border-color: var(--violet-light); color: var(--violet-light); font-weight: 600;"><i
|
|
615
|
+
data-lucide="archive" style="width: 14px; height: 14px;"></i> Export Project (.zip)</button>
|
|
616
|
+
<button id="downloadCsvBtn" class="btn-secondary"><i data-lucide="download"
|
|
617
|
+
style="width: 14px; height: 14px;"></i> Download Cleaned CSV</button>
|
|
618
|
+
<button id="reRunBtn" class="btn-ghost"><i data-lucide="refresh-cw" style="width: 14px; height: 14px;"></i>
|
|
619
|
+
Re-run Agentic Analysis</button>
|
|
620
|
+
</div>
|
|
621
|
+
|
|
622
|
+
</section><!-- /results screen -->
|
|
623
|
+
|
|
624
|
+
</main><!-- /main-area -->
|
|
625
|
+
|
|
626
|
+
<!-- Schema Relation Modal -->
|
|
627
|
+
<div id="relationModal" class="modal-overlay hidden">
|
|
628
|
+
<div class="modal-box"
|
|
629
|
+
style="max-width: 480px; padding: 24px; border: 1px solid rgba(34, 211, 238, 0.3); background: rgba(18, 18, 22, 0.98); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); border-radius: var(--r-md);">
|
|
630
|
+
<div class="modal-header"
|
|
631
|
+
style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px;">
|
|
632
|
+
<h2 id="relationModalTitle" style="margin: 0; font-size: 1.15rem; font-weight: 700; color: #fff;">Tweak
|
|
633
|
+
Relationship</h2>
|
|
634
|
+
<button id="closeRelationModalBtn"
|
|
635
|
+
style="background: transparent; border: none; font-size: 1.25rem; cursor: pointer; color: var(--text-secondary); width: auto; padding: 0;">✕</button>
|
|
636
|
+
</div>
|
|
637
|
+
<div class="modal-body" style="display: flex; flex-direction: column; gap: 14px; text-align: left;">
|
|
638
|
+
<div class="field-group" style="display: flex; flex-direction: column; gap: 4px;">
|
|
639
|
+
<label class="field-label" style="font-weight: 600; color: var(--text-secondary); font-size: 0.82rem;">X
|
|
640
|
+
Variable (Source Column)</label>
|
|
641
|
+
<select id="relationModalXSelect" class="field-input"
|
|
642
|
+
style="width:100%; box-sizing:border-box; background:var(--bg-card); color:var(--text-primary); border:1px solid var(--border-mid); border-radius:var(--r-sm); padding:8px;"></select>
|
|
643
|
+
</div>
|
|
644
|
+
<div class="field-group" style="display: flex; flex-direction: column; gap: 4px;">
|
|
645
|
+
<label class="field-label" style="font-weight: 600; color: var(--text-secondary); font-size: 0.82rem;">Y
|
|
646
|
+
Variable (Target Column)</label>
|
|
647
|
+
<select id="relationModalYSelect" class="field-input"
|
|
648
|
+
style="width:100%; box-sizing:border-box; background:var(--bg-card); color:var(--text-primary); border:1px solid var(--border-mid); border-radius:var(--r-sm); padding:8px;"></select>
|
|
649
|
+
</div>
|
|
650
|
+
<div class="field-group" style="display: flex; flex-direction: column; gap: 4px;">
|
|
651
|
+
<label class="field-label" style="font-weight: 600; color: var(--text-secondary); font-size: 0.82rem;">Visual
|
|
652
|
+
Plot Recommendation</label>
|
|
653
|
+
<select id="relationModalTypeSelect" class="field-input"
|
|
654
|
+
style="width:100%; box-sizing:border-box; background:var(--bg-card); color:var(--text-primary); border:1px solid var(--border-mid); border-radius:var(--r-sm); padding:8px;">
|
|
655
|
+
<option value="Scatter Plot">Scatter Plot</option>
|
|
656
|
+
<option value="Bar Chart">Bar Chart</option>
|
|
657
|
+
<option value="Line Chart">Line Chart</option>
|
|
658
|
+
<option value="Box Plot">Box Plot</option>
|
|
659
|
+
<option value="Histogram">Histogram</option>
|
|
660
|
+
<option value="Heatmap">Heatmap</option>
|
|
661
|
+
</select>
|
|
662
|
+
</div>
|
|
663
|
+
<div class="field-group" style="display: flex; flex-direction: column; gap: 4px;">
|
|
664
|
+
<label class="field-label"
|
|
665
|
+
style="font-weight: 600; color: var(--text-secondary); font-size: 0.82rem;">Correlation & Statistical
|
|
666
|
+
Details</label>
|
|
667
|
+
<textarea id="relationModalDetails" class="field-input" rows="3"
|
|
668
|
+
placeholder="Explain the relationship correlation or domain relevance..."
|
|
669
|
+
style="width:100%; box-sizing:border-box; font-family:inherit; resize:none; padding:8px; background:var(--bg-card); color:var(--text-primary); border:1px solid var(--border-mid); border-radius:var(--r-sm);"></textarea>
|
|
670
|
+
</div>
|
|
671
|
+
</div>
|
|
672
|
+
<div class="modal-footer" style="display: flex; justify-content: flex-end; gap: 10px; margin-top: 20px;">
|
|
673
|
+
<button id="relationModalCancelBtn" class="btn-secondary" style="padding: 8px 16px;">Cancel</button>
|
|
674
|
+
<button id="relationModalConfirmBtn" class="btn-primary" style="padding: 8px 16px;">Apply Changes</button>
|
|
675
|
+
</div>
|
|
676
|
+
</div>
|
|
677
|
+
</div>
|
|
678
|
+
|
|
679
|
+
<!-- API Warning Modal -->
|
|
680
|
+
<div id="apiWarningModal" class="modal-overlay hidden">
|
|
681
|
+
<div class="modal-box" style="max-width: 420px; text-align: center; padding: 30px;">
|
|
682
|
+
<div class="modal-icon" style="font-size: 3rem; margin-bottom: 15px;"><i data-lucide="key"
|
|
683
|
+
style="width: 48px; height: 48px; color: var(--violet-light);"></i></div>
|
|
684
|
+
<h2 style="margin-bottom: 10px;">API Key Required</h2>
|
|
685
|
+
<p style="font-size: 0.88rem; color: var(--text-secondary); line-height: 1.5; margin-bottom: 24px;">
|
|
686
|
+
An API key is required to run the analysis with <span id="warningProviderName"
|
|
687
|
+
style="color: var(--violet-light); font-weight: 600;"></span>. Let's configure it in your LLM Settings.
|
|
688
|
+
</p>
|
|
689
|
+
<div style="display: flex; flex-direction: column; gap: 10px;">
|
|
690
|
+
<button id="guideToApiBtn" class="btn-primary" style="width: 100%;">Configure API Key Now</button>
|
|
691
|
+
<button id="closeApiWarningBtn" class="btn-secondary" style="width: 100%;">Cancel</button>
|
|
692
|
+
</div>
|
|
693
|
+
</div>
|
|
694
|
+
</div>
|
|
695
|
+
|
|
696
|
+
<!-- ─── METRICS SCREEN ─── -->
|
|
697
|
+
<section id="metricsScreen" class="screen" style="padding: 24px; max-width: 1200px; margin: 0 auto; width: 100%; box-sizing: border-box;">
|
|
698
|
+
<div class="section-title-row" style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center; width: 100%;">
|
|
699
|
+
<h1 class="hero-title" style="margin: 0; font-size: 1.8rem; font-weight: 700; line-height: 1.2;"><span class="gradient-text">Performance Metrics</span></h1>
|
|
700
|
+
<button id="backToDashboardBtn" class="btn-secondary" style="padding: 8px 16px; border-radius: var(--r-sm); font-size: 0.85rem; cursor: pointer; display: flex; align-items: center; gap: 6px;"><i data-lucide="arrow-left" style="width: 14px; height: 14px;"></i> Back</button>
|
|
701
|
+
</div>
|
|
702
|
+
<p style="color: var(--text-secondary); margin-bottom: 24px; font-size: 0.9rem;">Track runtime performance, token consumption, and API costs across your data analysis runs.</p>
|
|
703
|
+
|
|
704
|
+
<!-- Metrics overview cards -->
|
|
705
|
+
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 20px; margin-bottom: 30px; width: 100%;">
|
|
706
|
+
<div class="stat-card" style="background: var(--bg-elevated); border: 1px solid var(--border); padding: 20px; border-radius: var(--r-md); box-sizing: border-box;">
|
|
707
|
+
<div style="font-size: 0.75rem; color: var(--text-secondary); font-weight: 600; margin-bottom: 8px; letter-spacing: 0.05em; text-transform: uppercase;">TOTAL RUNS</div>
|
|
708
|
+
<div id="metricsTotalRuns" style="font-size: 2rem; font-weight: 700; color: #fff;">0</div>
|
|
709
|
+
</div>
|
|
710
|
+
<div class="stat-card" style="background: var(--bg-elevated); border: 1px solid var(--border); padding: 20px; border-radius: var(--r-md); box-sizing: border-box;">
|
|
711
|
+
<div style="font-size: 0.75rem; color: var(--text-secondary); font-weight: 600; margin-bottom: 8px; letter-spacing: 0.05em; text-transform: uppercase;">AVG RUN TIME</div>
|
|
712
|
+
<div id="metricsAvgTime" style="font-size: 2rem; font-weight: 700; color: var(--violet-light);">0s</div>
|
|
713
|
+
</div>
|
|
714
|
+
<div class="stat-card" style="background: var(--bg-elevated); border: 1px solid var(--border); padding: 20px; border-radius: var(--r-md); box-sizing: border-box;">
|
|
715
|
+
<div style="font-size: 0.75rem; color: var(--text-secondary); font-weight: 600; margin-bottom: 8px; letter-spacing: 0.05em; text-transform: uppercase;">TOTAL TOKENS USED</div>
|
|
716
|
+
<div id="metricsTotalTokens" style="font-size: 2rem; font-weight: 700; color: var(--cyan);">0</div>
|
|
717
|
+
</div>
|
|
718
|
+
<div class="stat-card" style="background: var(--bg-elevated); border: 1px solid var(--border); padding: 20px; border-radius: var(--r-md); box-sizing: border-box;">
|
|
719
|
+
<div style="font-size: 0.75rem; color: var(--text-secondary); font-weight: 600; margin-bottom: 8px; letter-spacing: 0.05em; text-transform: uppercase;">ESTIMATED COST</div>
|
|
720
|
+
<div id="metricsTotalCost" style="font-size: 2rem; font-weight: 700; color: var(--amber);">$0.00</div>
|
|
721
|
+
</div>
|
|
722
|
+
</div>
|
|
723
|
+
|
|
724
|
+
<!-- Metrics table -->
|
|
725
|
+
<div style="background: var(--bg-elevated); border: 1px solid var(--border); border-radius: var(--r-md); overflow: hidden; width: 100%; box-sizing: border-box;">
|
|
726
|
+
<div style="padding: 16px 20px; border-bottom: 1px solid var(--border); font-weight: 600; color: #fff; font-size: 0.95rem; background: rgba(255,255,255,0.01);">Run Execution History</div>
|
|
727
|
+
<div style="overflow-x: auto; max-height: 400px; width: 100%;">
|
|
728
|
+
<table style="width: 100%; border-collapse: collapse; text-align: left; font-size: 0.88rem; min-width: 700px;">
|
|
729
|
+
<thead>
|
|
730
|
+
<tr style="border-bottom: 1px solid var(--border); color: var(--text-secondary); font-weight: 600; background: rgba(0,0,0,0.15);">
|
|
731
|
+
<th style="padding: 12px 20px;">Dataset</th>
|
|
732
|
+
<th style="padding: 12px 20px;">Shape</th>
|
|
733
|
+
<th style="padding: 12px 20px;">Total Duration</th>
|
|
734
|
+
<th style="padding: 12px 20px;">Tokens Used</th>
|
|
735
|
+
<th style="padding: 12px 20px;">Estimated Cost</th>
|
|
736
|
+
<th style="padding: 12px 20px;">Timestamp</th>
|
|
737
|
+
<th style="padding: 12px 20px;">Status</th>
|
|
738
|
+
</tr>
|
|
739
|
+
</thead>
|
|
740
|
+
<tbody id="metricsTableBody">
|
|
741
|
+
<!-- Rendered dynamically -->
|
|
742
|
+
</tbody>
|
|
743
|
+
</table>
|
|
744
|
+
</div>
|
|
745
|
+
</div>
|
|
746
|
+
</section>
|
|
747
|
+
|
|
748
|
+
<!-- Settings Modal -->
|
|
749
|
+
<div id="settingsModal" class="modal-overlay hidden">
|
|
750
|
+
<div class="modal-box" style="max-width: 500px;">
|
|
751
|
+
<div class="modal-header">
|
|
752
|
+
<h2><i data-lucide="settings" style="width: 20px; height: 20px; vertical-align: middle; margin-right: 6px;"></i>
|
|
753
|
+
API Credentials & Settings</h2>
|
|
754
|
+
<button id="closeSettingsModal" class="btn-icon">✕</button>
|
|
755
|
+
</div>
|
|
756
|
+
|
|
757
|
+
<div class="modal-body"
|
|
758
|
+
style="display: flex; flex-direction: column; gap: 14px; max-height: 520px; overflow-y: auto; padding-right: 4px;">
|
|
759
|
+
<p class="modal-hint">Configure API keys for each LLM provider. Keys are saved securely in your browser.
|
|
760
|
+
Check/uncheck "Show in sidebar" to filter the options on your dashboard.</p>
|
|
761
|
+
|
|
762
|
+
<!-- Provider Key inputs -->
|
|
763
|
+
<div style="display: flex; flex-direction: column; gap: 14px;">
|
|
764
|
+
<!-- NVIDIA -->
|
|
765
|
+
<div class="setting-row">
|
|
766
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
767
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">NVIDIA NIM API Key</label>
|
|
768
|
+
<label
|
|
769
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
770
|
+
<input type="checkbox" id="showNvidia" class="setting-show-checkbox" checked /> Show in sidebar
|
|
771
|
+
</label>
|
|
772
|
+
</div>
|
|
773
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
774
|
+
<input type="password" id="keyNvidia" class="field-input setting-key" placeholder="Enter key…"
|
|
775
|
+
style="flex: 1;" />
|
|
776
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
777
|
+
<button class="btn-secondary test-individual-btn" data-provider="nvidia"
|
|
778
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
779
|
+
</div>
|
|
780
|
+
<div class="individual-status" id="statusNvidia"
|
|
781
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
782
|
+
</div>
|
|
783
|
+
|
|
784
|
+
<!-- Groq -->
|
|
785
|
+
<div class="setting-row">
|
|
786
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
787
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">Groq API Key</label>
|
|
788
|
+
<label
|
|
789
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
790
|
+
<input type="checkbox" id="showGroq" class="setting-show-checkbox" checked /> Show in sidebar
|
|
791
|
+
</label>
|
|
792
|
+
</div>
|
|
793
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
794
|
+
<input type="password" id="keyGroq" class="field-input setting-key" placeholder="Enter key…"
|
|
795
|
+
style="flex: 1;" />
|
|
796
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
797
|
+
<button class="btn-secondary test-individual-btn" data-provider="groq"
|
|
798
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
799
|
+
</div>
|
|
800
|
+
<div class="individual-status" id="statusGroq"
|
|
801
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
802
|
+
</div>
|
|
803
|
+
|
|
804
|
+
<!-- OpenAI -->
|
|
805
|
+
<div class="setting-row">
|
|
806
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
807
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">OpenAI API Key</label>
|
|
808
|
+
<label
|
|
809
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
810
|
+
<input type="checkbox" id="showOpenai" class="setting-show-checkbox" checked /> Show in sidebar
|
|
811
|
+
</label>
|
|
812
|
+
</div>
|
|
813
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
814
|
+
<input type="password" id="keyOpenai" class="field-input setting-key" placeholder="Enter key…"
|
|
815
|
+
style="flex: 1;" />
|
|
816
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
817
|
+
<button class="btn-secondary test-individual-btn" data-provider="openai"
|
|
818
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
819
|
+
</div>
|
|
820
|
+
<div class="individual-status" id="statusOpenai"
|
|
821
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
822
|
+
</div>
|
|
823
|
+
|
|
824
|
+
<!-- Anthropic -->
|
|
825
|
+
<div class="setting-row">
|
|
826
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
827
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">Anthropic API Key</label>
|
|
828
|
+
<label
|
|
829
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
830
|
+
<input type="checkbox" id="showAnthropic" class="setting-show-checkbox" checked /> Show in sidebar
|
|
831
|
+
</label>
|
|
832
|
+
</div>
|
|
833
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
834
|
+
<input type="password" id="keyAnthropic" class="field-input setting-key" placeholder="Enter key…"
|
|
835
|
+
style="flex: 1;" />
|
|
836
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
837
|
+
<button class="btn-secondary test-individual-btn" data-provider="anthropic"
|
|
838
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
839
|
+
</div>
|
|
840
|
+
<div class="individual-status" id="statusAnthropic"
|
|
841
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
842
|
+
</div>
|
|
843
|
+
|
|
844
|
+
<!-- Google Gemini -->
|
|
845
|
+
<div class="setting-row">
|
|
846
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
847
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">Google Gemini API Key</label>
|
|
848
|
+
<label
|
|
849
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
850
|
+
<input type="checkbox" id="showGemini" class="setting-show-checkbox" checked /> Show in sidebar
|
|
851
|
+
</label>
|
|
852
|
+
</div>
|
|
853
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
854
|
+
<input type="password" id="keyGemini" class="field-input setting-key" placeholder="Enter key…"
|
|
855
|
+
style="flex: 1;" />
|
|
856
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
857
|
+
<button class="btn-secondary test-individual-btn" data-provider="gemini"
|
|
858
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
859
|
+
</div>
|
|
860
|
+
<div class="individual-status" id="statusGemini"
|
|
861
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
862
|
+
</div>
|
|
863
|
+
|
|
864
|
+
<!-- Mistral -->
|
|
865
|
+
<div class="setting-row">
|
|
866
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
867
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">Mistral API Key</label>
|
|
868
|
+
<label
|
|
869
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
870
|
+
<input type="checkbox" id="showMistral" class="setting-show-checkbox" checked /> Show in sidebar
|
|
871
|
+
</label>
|
|
872
|
+
</div>
|
|
873
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
874
|
+
<input type="password" id="keyMistral" class="field-input setting-key" placeholder="Enter key…"
|
|
875
|
+
style="flex: 1;" />
|
|
876
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
877
|
+
<button class="btn-secondary test-individual-btn" data-provider="mistral"
|
|
878
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
879
|
+
</div>
|
|
880
|
+
<div class="individual-status" id="statusMistral"
|
|
881
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
882
|
+
</div>
|
|
883
|
+
|
|
884
|
+
<!-- HuggingFace -->
|
|
885
|
+
<div class="setting-row">
|
|
886
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
887
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">HuggingFace API Key</label>
|
|
888
|
+
<label
|
|
889
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
890
|
+
<input type="checkbox" id="showHuggingface" class="setting-show-checkbox" checked /> Show in sidebar
|
|
891
|
+
</label>
|
|
892
|
+
</div>
|
|
893
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
894
|
+
<input type="password" id="keyHuggingface" class="field-input setting-key" placeholder="Enter key…"
|
|
895
|
+
style="flex: 1;" />
|
|
896
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
897
|
+
<button class="btn-secondary test-individual-btn" data-provider="huggingface"
|
|
898
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
899
|
+
</div>
|
|
900
|
+
<div class="individual-status" id="statusHuggingface"
|
|
901
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
902
|
+
</div>
|
|
903
|
+
|
|
904
|
+
<!-- Cohere -->
|
|
905
|
+
<div class="setting-row">
|
|
906
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
907
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">Cohere API Key</label>
|
|
908
|
+
<label
|
|
909
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
910
|
+
<input type="checkbox" id="showCohere" class="setting-show-checkbox" checked /> Show in sidebar
|
|
911
|
+
</label>
|
|
912
|
+
</div>
|
|
913
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
914
|
+
<input type="password" id="keyCohere" class="field-input setting-key" placeholder="Enter key…"
|
|
915
|
+
style="flex: 1;" />
|
|
916
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
917
|
+
<button class="btn-secondary test-individual-btn" data-provider="cohere"
|
|
918
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
919
|
+
</div>
|
|
920
|
+
<div class="individual-status" id="statusCohere"
|
|
921
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
922
|
+
</div>
|
|
923
|
+
|
|
924
|
+
<!-- TogetherAI -->
|
|
925
|
+
<div class="setting-row">
|
|
926
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
927
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">TogetherAI API Key</label>
|
|
928
|
+
<label
|
|
929
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
930
|
+
<input type="checkbox" id="showTogether" class="setting-show-checkbox" checked /> Show in sidebar
|
|
931
|
+
</label>
|
|
932
|
+
</div>
|
|
933
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
934
|
+
<input type="password" id="keyTogether" class="field-input setting-key" placeholder="Enter key…"
|
|
935
|
+
style="flex: 1;" />
|
|
936
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
937
|
+
<button class="btn-secondary test-individual-btn" data-provider="together"
|
|
938
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
939
|
+
</div>
|
|
940
|
+
<div class="individual-status" id="statusTogether"
|
|
941
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
942
|
+
</div>
|
|
943
|
+
|
|
944
|
+
<!-- OpenRouter -->
|
|
945
|
+
<div class="setting-row">
|
|
946
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
947
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">OpenRouter API Key</label>
|
|
948
|
+
<label
|
|
949
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
950
|
+
<input type="checkbox" id="showOpenrouter" class="setting-show-checkbox" checked /> Show in sidebar
|
|
951
|
+
</label>
|
|
952
|
+
</div>
|
|
953
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
954
|
+
<input type="password" id="keyOpenrouter" class="field-input setting-key" placeholder="Enter key…"
|
|
955
|
+
style="flex: 1;" />
|
|
956
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
957
|
+
<button class="btn-secondary test-individual-btn" data-provider="openrouter"
|
|
958
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
959
|
+
</div>
|
|
960
|
+
<div class="individual-status" id="statusOpenrouter"
|
|
961
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
962
|
+
</div>
|
|
963
|
+
|
|
964
|
+
<!-- DeepSeek -->
|
|
965
|
+
<div class="setting-row">
|
|
966
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
967
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">DeepSeek API Key</label>
|
|
968
|
+
<label
|
|
969
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
970
|
+
<input type="checkbox" id="showDeepseek" class="setting-show-checkbox" checked /> Show in sidebar
|
|
971
|
+
</label>
|
|
972
|
+
</div>
|
|
973
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
974
|
+
<input type="password" id="keyDeepseek" class="field-input setting-key" placeholder="Enter key…"
|
|
975
|
+
style="flex: 1;" />
|
|
976
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
977
|
+
<button class="btn-secondary test-individual-btn" data-provider="deepseek"
|
|
978
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
979
|
+
</div>
|
|
980
|
+
<div class="individual-status" id="statusDeepseek"
|
|
981
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
982
|
+
</div>
|
|
983
|
+
|
|
984
|
+
<!-- Perplexity -->
|
|
985
|
+
<div class="setting-row">
|
|
986
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
987
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">Perplexity API Key</label>
|
|
988
|
+
<label
|
|
989
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
990
|
+
<input type="checkbox" id="showPerplexity" class="setting-show-checkbox" checked /> Show in sidebar
|
|
991
|
+
</label>
|
|
992
|
+
</div>
|
|
993
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
994
|
+
<input type="password" id="keyPerplexity" class="field-input setting-key" placeholder="Enter key…"
|
|
995
|
+
style="flex: 1;" />
|
|
996
|
+
<button class="btn-eye toggle-setting-key" title="Show/hide key" style="padding: 0 10px;">👁</button>
|
|
997
|
+
<button class="btn-secondary test-individual-btn" data-provider="perplexity"
|
|
998
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
999
|
+
</div>
|
|
1000
|
+
<div class="individual-status" id="statusPerplexity"
|
|
1001
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
1002
|
+
</div>
|
|
1003
|
+
|
|
1004
|
+
<!-- Ollama Base URL -->
|
|
1005
|
+
<div class="setting-row">
|
|
1006
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
1007
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">Ollama Base URL</label>
|
|
1008
|
+
<label
|
|
1009
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
1010
|
+
<input type="checkbox" id="showOllama" class="setting-show-checkbox" checked /> Show in sidebar
|
|
1011
|
+
</label>
|
|
1012
|
+
</div>
|
|
1013
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
1014
|
+
<input type="text" id="urlOllama" class="field-input setting-key" placeholder="http://localhost:11434"
|
|
1015
|
+
style="flex: 1;" />
|
|
1016
|
+
<button class="btn-secondary test-individual-btn" data-provider="ollama"
|
|
1017
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
1018
|
+
</div>
|
|
1019
|
+
<div class="individual-status" id="statusOllama"
|
|
1020
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
1021
|
+
</div>
|
|
1022
|
+
|
|
1023
|
+
<!-- Custom API URL & Key -->
|
|
1024
|
+
<div class="setting-row">
|
|
1025
|
+
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px;">
|
|
1026
|
+
<label class="field-label" style="margin-bottom: 0; font-weight: 600;">Custom Base URL & Key</label>
|
|
1027
|
+
<label
|
|
1028
|
+
style="display: inline-flex; align-items: center; gap: 6px; font-size: 0.72rem; color: var(--text-secondary); cursor: pointer;">
|
|
1029
|
+
<input type="checkbox" id="showCustom" class="setting-show-checkbox" checked /> Show in sidebar
|
|
1030
|
+
</label>
|
|
1031
|
+
</div>
|
|
1032
|
+
<div class="key-input-wrap" style="display: flex; gap: 8px;">
|
|
1033
|
+
<input type="text" id="urlCustom" class="field-input setting-key" placeholder="https://api.your-provider.com/v1"
|
|
1034
|
+
style="flex: 1;" />
|
|
1035
|
+
<input type="password" id="keyCustom" class="field-input setting-key" placeholder="Enter key…"
|
|
1036
|
+
style="flex: 1;" />
|
|
1037
|
+
<button class="btn-secondary test-individual-btn" data-provider="custom"
|
|
1038
|
+
style="padding: 0 12px; font-size: 0.75rem; white-space: nowrap;">🔌 Test</button>
|
|
1039
|
+
</div>
|
|
1040
|
+
<div class="individual-status" id="statusCustom"
|
|
1041
|
+
style="font-size: 0.72rem; margin-top: 4px; min-height: 14px;"></div>
|
|
1042
|
+
</div>
|
|
1043
|
+
</div>
|
|
1044
|
+
|
|
1045
|
+
<hr style="border: none; border-top: 1px solid var(--border); margin: 8px 0;" />
|
|
1046
|
+
|
|
1047
|
+
<!-- Cooldown -->
|
|
1048
|
+
<div>
|
|
1049
|
+
<label class="field-label" style="display: block; margin-bottom: 6px;">API Cooldown: <span
|
|
1050
|
+
id="settingsCooldownVal">5</span>s</label>
|
|
1051
|
+
<input type="range" id="settingsCooldown" class="field-range" min="0" max="60" value="5" />
|
|
1052
|
+
</div>
|
|
1053
|
+
</div>
|
|
1054
|
+
|
|
1055
|
+
<div class="modal-footer">
|
|
1056
|
+
<button id="cancelSettingsBtn" class="btn-secondary">Close</button>
|
|
1057
|
+
<button id="saveSettingsBtn" class="btn-primary">Save Settings</button>
|
|
1058
|
+
</div>
|
|
1059
|
+
</div>
|
|
1060
|
+
</div>
|
|
1061
|
+
|
|
1062
|
+
<!-- Custom Dialog Modal (Alert/Confirm/Prompt) -->
|
|
1063
|
+
<div id="customDialogModal" class="modal-overlay hidden">
|
|
1064
|
+
<div class="modal-box" style="max-width: 460px;">
|
|
1065
|
+
<div class="modal-header">
|
|
1066
|
+
<h2 id="customDialogTitle">Confirm Action</h2>
|
|
1067
|
+
<button id="closeCustomDialogBtn" class="btn-icon">✕</button>
|
|
1068
|
+
</div>
|
|
1069
|
+
<div class="modal-body" style="gap: 16px; padding: 24px;">
|
|
1070
|
+
<p id="customDialogMessage"
|
|
1071
|
+
style="font-size: 0.92rem; line-height: 1.6; color: var(--text-secondary); margin: 0;"></p>
|
|
1072
|
+
<div id="customDialogPromptContainer" class="field-group hidden" style="margin-top: 8px;">
|
|
1073
|
+
<input type="text" id="customDialogInput" class="field-input"
|
|
1074
|
+
style="width: 100%; text-align: left; font-size: 0.95rem; padding: 10px 14px;" />
|
|
1075
|
+
</div>
|
|
1076
|
+
</div>
|
|
1077
|
+
<div class="modal-footer" style="padding: 16px 24px; background: rgba(0,0,0,0.15);">
|
|
1078
|
+
<button id="customDialogCancelBtn" class="btn-secondary">Cancel</button>
|
|
1079
|
+
<button id="customDialogConfirmBtn" class="btn-primary">Confirm</button>
|
|
1080
|
+
</div>
|
|
1081
|
+
</div>
|
|
1082
|
+
</div>
|
|
1083
|
+
|
|
1084
|
+
<!-- Floating Analysis Notification Widget (Top Right) -->
|
|
1085
|
+
<div id="analysisNotification" class="analysis-notification-toast hidden">
|
|
1086
|
+
<button id="dismissNotif" class="notif-close-btn">×</button>
|
|
1087
|
+
<div class="notification-body">
|
|
1088
|
+
<div class="notif-spinner"></div>
|
|
1089
|
+
<div class="notif-content">
|
|
1090
|
+
<div class="notif-title">Crewlyze Analysis Active</div>
|
|
1091
|
+
<div class="notif-details"><span id="notifActiveJob">Cleaning...</span> | <span id="notifTimer">00:00</span>
|
|
1092
|
+
</div>
|
|
1093
|
+
</div>
|
|
1094
|
+
<button id="btnMaximizeNotif" class="btn-primary btn-xs"
|
|
1095
|
+
style="padding: 6px 10px; font-size: 0.75rem; font-weight: 600; border-radius: var(--r-md);">View</button>
|
|
1096
|
+
</div>
|
|
1097
|
+
</div>
|
|
1098
|
+
|
|
1099
|
+
<!-- Toast notifications -->
|
|
1100
|
+
<div id="toastContainer" class="toast-container"></div>
|
|
1101
|
+
|
|
1102
|
+
<script src="/app.js"></script>
|
|
1103
|
+
</body>
|
|
1104
|
+
|
|
1105
|
+
</html>
|