deepcode-hku 1.0.1__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.
- cli/__init__.py +18 -0
- cli/cli_app.py +296 -0
- cli/cli_interface.py +744 -0
- cli/cli_launcher.py +155 -0
- cli/main_cli.py +243 -0
- cli/workflows/__init__.py +11 -0
- cli/workflows/cli_workflow_adapter.py +336 -0
- deepcode.py +219 -0
- deepcode_hku-1.0.1.dist-info/METADATA +695 -0
- deepcode_hku-1.0.1.dist-info/RECORD +44 -0
- deepcode_hku-1.0.1.dist-info/WHEEL +5 -0
- deepcode_hku-1.0.1.dist-info/entry_points.txt +2 -0
- deepcode_hku-1.0.1.dist-info/licenses/LICENSE +21 -0
- deepcode_hku-1.0.1.dist-info/top_level.txt +6 -0
- tools/__init__.py +0 -0
- tools/code_implementation_server.py +1045 -0
- tools/code_indexer.py +1657 -0
- tools/code_reference_indexer.py +486 -0
- tools/command_executor.py +324 -0
- tools/git_command.py +356 -0
- tools/pdf_converter.py +640 -0
- tools/pdf_downloader.py +1370 -0
- tools/pdf_utils.py +52 -0
- ui/__init__.py +43 -0
- ui/app.py +13 -0
- ui/components.py +1450 -0
- ui/handlers.py +773 -0
- ui/layout.py +106 -0
- ui/streamlit_app.py +38 -0
- ui/styles.py +2116 -0
- utils/__init__.py +17 -0
- utils/cli_interface.py +459 -0
- utils/dialogue_logger.py +671 -0
- utils/file_processor.py +426 -0
- utils/simple_llm_logger.py +198 -0
- workflows/__init__.py +31 -0
- workflows/agent_orchestration_engine.py +1371 -0
- workflows/agents/__init__.py +13 -0
- workflows/agents/code_implementation_agent.py +1093 -0
- workflows/agents/memory_agent_concise.py +923 -0
- workflows/agents/memory_agent_concise_index.py +935 -0
- workflows/code_implementation_workflow.py +924 -0
- workflows/code_implementation_workflow_index.py +931 -0
- workflows/codebase_index_workflow.py +726 -0
ui/components.py
ADDED
|
@@ -0,0 +1,1450 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Streamlit UI Components Module
|
|
3
|
+
|
|
4
|
+
Contains all reusable UI components
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import streamlit as st
|
|
8
|
+
import sys
|
|
9
|
+
from typing import Dict, Any, Optional
|
|
10
|
+
from datetime import datetime
|
|
11
|
+
import json
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def display_header():
|
|
15
|
+
"""Display application header"""
|
|
16
|
+
st.markdown(
|
|
17
|
+
"""
|
|
18
|
+
<div class="main-header">
|
|
19
|
+
<h1>🧬 DeepCode</h1>
|
|
20
|
+
<h3>OPEN-SOURCE CODE AGENT</h3>
|
|
21
|
+
<p>⚡ DATA INTELLIGENCE LAB @ HKU • REVOLUTIONIZING RESEARCH REPRODUCIBILITY ⚡</p>
|
|
22
|
+
</div>
|
|
23
|
+
""",
|
|
24
|
+
unsafe_allow_html=True,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def display_features():
|
|
29
|
+
"""Display DeepCode AI Agent capabilities"""
|
|
30
|
+
# AI Agent core capabilities display area - updated to match README content
|
|
31
|
+
st.markdown(
|
|
32
|
+
"""
|
|
33
|
+
<div class="ai-capabilities-section">
|
|
34
|
+
<div class="neural-network">
|
|
35
|
+
<div class="neuron pulse-1"></div>
|
|
36
|
+
<div class="neuron pulse-2"></div>
|
|
37
|
+
<div class="neuron pulse-3"></div>
|
|
38
|
+
</div>
|
|
39
|
+
<h2 class="capabilities-title">🧠 Open Agentic Coding Platform</h2>
|
|
40
|
+
<p class="capabilities-subtitle">Advancing Code Generation with Multi-Agent Systems</p>
|
|
41
|
+
</div>
|
|
42
|
+
""",
|
|
43
|
+
unsafe_allow_html=True,
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
# Core functionality modules - Vertical Layout
|
|
47
|
+
st.markdown(
|
|
48
|
+
"""
|
|
49
|
+
<div class="feature-card-vertical primary">
|
|
50
|
+
<div class="card-glow-vertical"></div>
|
|
51
|
+
<div class="feature-header">
|
|
52
|
+
<div class="feature-logo-container">
|
|
53
|
+
<div class="ai-brain-logo">
|
|
54
|
+
<div class="brain-node node-1"></div>
|
|
55
|
+
<div class="brain-node node-2"></div>
|
|
56
|
+
<div class="brain-node node-3"></div>
|
|
57
|
+
<div class="brain-connection conn-1"></div>
|
|
58
|
+
<div class="brain-connection conn-2"></div>
|
|
59
|
+
</div>
|
|
60
|
+
<div class="feature-icon-large">🚀</div>
|
|
61
|
+
</div>
|
|
62
|
+
<div class="feature-header-content">
|
|
63
|
+
<h3 class="feature-title-large">Paper2Code: Research-to-Production Pipeline</h3>
|
|
64
|
+
<p class="feature-subtitle">Automated Implementation of Complex Algorithms</p>
|
|
65
|
+
</div>
|
|
66
|
+
<div class="feature-stats">
|
|
67
|
+
<div class="stat-item">
|
|
68
|
+
<span class="stat-number typing-number">Multi-Modal</span>
|
|
69
|
+
<span class="stat-label">Analysis</span>
|
|
70
|
+
</div>
|
|
71
|
+
<div class="stat-item">
|
|
72
|
+
<span class="stat-number typing-number">Production</span>
|
|
73
|
+
<span class="stat-label">Ready</span>
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
</div>
|
|
77
|
+
<div class="feature-content">
|
|
78
|
+
<div class="content-left">
|
|
79
|
+
<p class="feature-description-large">Multi-modal document analysis engine that extracts algorithmic logic and mathematical models from academic papers, generating optimized implementations with proper data structures while preserving computational complexity characteristics.</p>
|
|
80
|
+
<div class="feature-flow">
|
|
81
|
+
<div class="flow-step active">
|
|
82
|
+
<div class="flow-icon">📄</div>
|
|
83
|
+
<span>Document Parsing</span>
|
|
84
|
+
</div>
|
|
85
|
+
<div class="flow-arrow">→</div>
|
|
86
|
+
<div class="flow-step active">
|
|
87
|
+
<div class="flow-icon">🧠</div>
|
|
88
|
+
<span>Algorithm Extraction</span>
|
|
89
|
+
</div>
|
|
90
|
+
<div class="flow-arrow">→</div>
|
|
91
|
+
<div class="flow-step active">
|
|
92
|
+
<div class="flow-icon">⚡</div>
|
|
93
|
+
<span>Code Synthesis</span>
|
|
94
|
+
</div>
|
|
95
|
+
<div class="flow-arrow">→</div>
|
|
96
|
+
<div class="flow-step active">
|
|
97
|
+
<div class="flow-icon">✅</div>
|
|
98
|
+
<span>Quality Assurance</span>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
</div>
|
|
102
|
+
<div class="content-right">
|
|
103
|
+
<div class="code-simulation">
|
|
104
|
+
<div class="code-header">
|
|
105
|
+
<span class="code-lang">Python</span>
|
|
106
|
+
<div class="code-status generating">Generating...</div>
|
|
107
|
+
</div>
|
|
108
|
+
<div class="code-lines">
|
|
109
|
+
<div class="code-line typing">import torch</div>
|
|
110
|
+
<div class="code-line typing delay-1">import torch.nn as nn</div>
|
|
111
|
+
<div class="code-line typing delay-2">class ResearchAlgorithm(nn.Module):</div>
|
|
112
|
+
<div class="code-line typing delay-3"> def __init__(self, config):</div>
|
|
113
|
+
<div class="code-line typing delay-4"> super().__init__()</div>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
""",
|
|
120
|
+
unsafe_allow_html=True,
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
st.markdown(
|
|
124
|
+
"""
|
|
125
|
+
<div class="feature-card-vertical secondary">
|
|
126
|
+
<div class="card-glow-vertical"></div>
|
|
127
|
+
<div class="feature-header">
|
|
128
|
+
<div class="feature-logo-container">
|
|
129
|
+
<div class="multi-agent-logo">
|
|
130
|
+
<div class="agent-node agent-1">🎨</div>
|
|
131
|
+
<div class="agent-node agent-2">💻</div>
|
|
132
|
+
<div class="agent-node agent-3">⚡</div>
|
|
133
|
+
<div class="agent-connection conn-12"></div>
|
|
134
|
+
<div class="agent-connection conn-23"></div>
|
|
135
|
+
<div class="agent-connection conn-13"></div>
|
|
136
|
+
</div>
|
|
137
|
+
<div class="feature-icon-large">🎨</div>
|
|
138
|
+
</div>
|
|
139
|
+
<div class="feature-header-content">
|
|
140
|
+
<h3 class="feature-title-large">Text2Web: Automated Prototyping Engine</h3>
|
|
141
|
+
<p class="feature-subtitle">Natural Language to Front-End Code Synthesis</p>
|
|
142
|
+
</div>
|
|
143
|
+
<div class="feature-stats">
|
|
144
|
+
<div class="stat-item">
|
|
145
|
+
<span class="stat-number typing-number">Intelligent</span>
|
|
146
|
+
<span class="stat-label">Scaffolding</span>
|
|
147
|
+
</div>
|
|
148
|
+
<div class="stat-item">
|
|
149
|
+
<span class="stat-number typing-number">Scalable</span>
|
|
150
|
+
<span class="stat-label">Architecture</span>
|
|
151
|
+
</div>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
<div class="feature-content">
|
|
155
|
+
<div class="content-left">
|
|
156
|
+
<p class="feature-description-large">Context-aware code generation using fine-tuned language models. Intelligent scaffolding system generating complete application structures including frontend components, maintaining architectural consistency across modules.</p>
|
|
157
|
+
<div class="agent-grid">
|
|
158
|
+
<div class="agent-card active">
|
|
159
|
+
<div class="agent-avatar">📝</div>
|
|
160
|
+
<h4>Intent Understanding</h4>
|
|
161
|
+
<p>Semantic analysis of requirements</p>
|
|
162
|
+
</div>
|
|
163
|
+
<div class="agent-card active">
|
|
164
|
+
<div class="agent-avatar">🎨</div>
|
|
165
|
+
<h4>UI Architecture</h4>
|
|
166
|
+
<p>Component design & structure</p>
|
|
167
|
+
</div>
|
|
168
|
+
<div class="agent-card active">
|
|
169
|
+
<div class="agent-avatar">💻</div>
|
|
170
|
+
<h4>Code Generation</h4>
|
|
171
|
+
<p>Functional interface creation</p>
|
|
172
|
+
</div>
|
|
173
|
+
<div class="agent-card active">
|
|
174
|
+
<div class="agent-avatar">✨</div>
|
|
175
|
+
<h4>Quality Assurance</h4>
|
|
176
|
+
<p>Automated testing & validation</p>
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
</div>
|
|
180
|
+
<div class="content-right">
|
|
181
|
+
<div class="collaboration-viz">
|
|
182
|
+
<div class="collaboration-center">
|
|
183
|
+
<div class="center-node">🎯</div>
|
|
184
|
+
<span>Web Application</span>
|
|
185
|
+
</div>
|
|
186
|
+
<div class="collaboration-agents">
|
|
187
|
+
<div class="collab-agent agent-pos-1">
|
|
188
|
+
<div class="pulse-ring"></div>
|
|
189
|
+
📝
|
|
190
|
+
</div>
|
|
191
|
+
<div class="collab-agent agent-pos-2">
|
|
192
|
+
<div class="pulse-ring"></div>
|
|
193
|
+
🏗️
|
|
194
|
+
</div>
|
|
195
|
+
<div class="collab-agent agent-pos-3">
|
|
196
|
+
<div class="pulse-ring"></div>
|
|
197
|
+
⚙️
|
|
198
|
+
</div>
|
|
199
|
+
<div class="collab-agent agent-pos-4">
|
|
200
|
+
<div class="pulse-ring"></div>
|
|
201
|
+
🧪
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
""",
|
|
209
|
+
unsafe_allow_html=True,
|
|
210
|
+
)
|
|
211
|
+
|
|
212
|
+
st.markdown(
|
|
213
|
+
"""
|
|
214
|
+
<div class="feature-card-vertical accent">
|
|
215
|
+
<div class="card-glow-vertical"></div>
|
|
216
|
+
<div class="feature-header">
|
|
217
|
+
<div class="feature-logo-container">
|
|
218
|
+
<div class="future-logo">
|
|
219
|
+
<div class="orbit orbit-1">
|
|
220
|
+
<div class="orbit-node">⚙️</div>
|
|
221
|
+
</div>
|
|
222
|
+
<div class="orbit orbit-2">
|
|
223
|
+
<div class="orbit-node">🔧</div>
|
|
224
|
+
</div>
|
|
225
|
+
<div class="orbit-center">🚀</div>
|
|
226
|
+
</div>
|
|
227
|
+
<div class="feature-icon-large">⚙️</div>
|
|
228
|
+
</div>
|
|
229
|
+
<div class="feature-header-content">
|
|
230
|
+
<h3 class="feature-title-large">Text2Backend: Scalable Architecture Generator</h3>
|
|
231
|
+
<p class="feature-subtitle">Intelligent Server-Side Development</p>
|
|
232
|
+
</div>
|
|
233
|
+
<div class="feature-stats">
|
|
234
|
+
<div class="stat-item">
|
|
235
|
+
<span class="stat-number typing-number">Database</span>
|
|
236
|
+
<span class="stat-label">Integration</span>
|
|
237
|
+
</div>
|
|
238
|
+
<div class="stat-item">
|
|
239
|
+
<span class="stat-number typing-number">API</span>
|
|
240
|
+
<span class="stat-label">Endpoints</span>
|
|
241
|
+
</div>
|
|
242
|
+
</div>
|
|
243
|
+
</div>
|
|
244
|
+
<div class="feature-content">
|
|
245
|
+
<div class="content-left">
|
|
246
|
+
<p class="feature-description-large">Generates efficient, scalable backend systems with database schemas, API endpoints, and microservices architecture. Uses dependency analysis to ensure scalable architecture from initial generation with comprehensive testing.</p>
|
|
247
|
+
<div class="vision-demo">
|
|
248
|
+
<div class="demo-input">
|
|
249
|
+
<div class="input-icon">💬</div>
|
|
250
|
+
<div class="input-text typing">"Build a scalable e-commerce API with user authentication and payment processing"</div>
|
|
251
|
+
</div>
|
|
252
|
+
<div class="demo-arrow">⬇️</div>
|
|
253
|
+
<div class="demo-output">
|
|
254
|
+
<div class="output-items">
|
|
255
|
+
<div class="output-item">🏗️ Microservices Architecture</div>
|
|
256
|
+
<div class="output-item">🔒 Authentication & Security</div>
|
|
257
|
+
<div class="output-item">🗄️ Database Schema Design</div>
|
|
258
|
+
<div class="output-item">📊 API Documentation & Testing</div>
|
|
259
|
+
</div>
|
|
260
|
+
</div>
|
|
261
|
+
</div>
|
|
262
|
+
</div>
|
|
263
|
+
<div class="content-right">
|
|
264
|
+
<div class="future-timeline">
|
|
265
|
+
<div class="timeline-item completed">
|
|
266
|
+
<div class="timeline-marker">✅</div>
|
|
267
|
+
<div class="timeline-content">
|
|
268
|
+
<h4>API Design</h4>
|
|
269
|
+
<p>RESTful endpoints</p>
|
|
270
|
+
</div>
|
|
271
|
+
</div>
|
|
272
|
+
<div class="timeline-item completed">
|
|
273
|
+
<div class="timeline-marker">✅</div>
|
|
274
|
+
<div class="timeline-content">
|
|
275
|
+
<h4>Database Layer</h4>
|
|
276
|
+
<p>Schema & relationships</p>
|
|
277
|
+
</div>
|
|
278
|
+
</div>
|
|
279
|
+
<div class="timeline-item active">
|
|
280
|
+
<div class="timeline-marker">🔄</div>
|
|
281
|
+
<div class="timeline-content">
|
|
282
|
+
<h4>Security Layer</h4>
|
|
283
|
+
<p>Authentication & authorization</p>
|
|
284
|
+
</div>
|
|
285
|
+
</div>
|
|
286
|
+
<div class="timeline-item future">
|
|
287
|
+
<div class="timeline-marker">🚀</div>
|
|
288
|
+
<div class="timeline-content">
|
|
289
|
+
<h4>Deployment</h4>
|
|
290
|
+
<p>CI/CD integration</p>
|
|
291
|
+
</div>
|
|
292
|
+
</div>
|
|
293
|
+
</div>
|
|
294
|
+
</div>
|
|
295
|
+
</div>
|
|
296
|
+
</div>
|
|
297
|
+
""",
|
|
298
|
+
unsafe_allow_html=True,
|
|
299
|
+
)
|
|
300
|
+
|
|
301
|
+
st.markdown(
|
|
302
|
+
"""
|
|
303
|
+
<div class="feature-card-vertical tech">
|
|
304
|
+
<div class="card-glow-vertical"></div>
|
|
305
|
+
<div class="feature-header">
|
|
306
|
+
<div class="feature-logo-container">
|
|
307
|
+
<div class="opensource-logo">
|
|
308
|
+
<div class="github-stars">
|
|
309
|
+
<div class="star star-1">📄</div>
|
|
310
|
+
<div class="star star-2">🤖</div>
|
|
311
|
+
<div class="star star-3">⚡</div>
|
|
312
|
+
</div>
|
|
313
|
+
<div class="community-nodes">
|
|
314
|
+
<div class="community-node">🧠</div>
|
|
315
|
+
<div class="community-node">🔍</div>
|
|
316
|
+
<div class="community-node">⚙️</div>
|
|
317
|
+
</div>
|
|
318
|
+
</div>
|
|
319
|
+
<div class="feature-icon-large">🎯</div>
|
|
320
|
+
</div>
|
|
321
|
+
<div class="feature-header-content">
|
|
322
|
+
<h3 class="feature-title-large">CodeRAG Integration System</h3>
|
|
323
|
+
<p class="feature-subtitle">Advanced Multi-Agent Orchestration</p>
|
|
324
|
+
</div>
|
|
325
|
+
<div class="feature-stats">
|
|
326
|
+
<div class="stat-item">
|
|
327
|
+
<span class="stat-number typing-number">Global</span>
|
|
328
|
+
<span class="stat-label">Code Analysis</span>
|
|
329
|
+
</div>
|
|
330
|
+
<div class="stat-item">
|
|
331
|
+
<span class="stat-number typing-number">Intelligent</span>
|
|
332
|
+
<span class="stat-label">Orchestration</span>
|
|
333
|
+
</div>
|
|
334
|
+
</div>
|
|
335
|
+
</div>
|
|
336
|
+
<div class="feature-content">
|
|
337
|
+
<div class="content-left">
|
|
338
|
+
<p class="feature-description-large">Advanced retrieval-augmented generation combining semantic vector embeddings with graph-based dependency analysis. Central orchestrating agent coordinates specialized agents with dynamic task planning and intelligent memory management.</p>
|
|
339
|
+
<div class="community-features">
|
|
340
|
+
<div class="community-feature">
|
|
341
|
+
<div class="feature-icon-small">🧠</div>
|
|
342
|
+
<div class="feature-text">
|
|
343
|
+
<h4>Intelligent Orchestration</h4>
|
|
344
|
+
<p>Central decision-making with dynamic planning algorithms</p>
|
|
345
|
+
</div>
|
|
346
|
+
</div>
|
|
347
|
+
<div class="community-feature">
|
|
348
|
+
<div class="feature-icon-small">🔍</div>
|
|
349
|
+
<div class="feature-text">
|
|
350
|
+
<h4>CodeRAG System</h4>
|
|
351
|
+
<p>Semantic analysis with dependency graph mapping</p>
|
|
352
|
+
</div>
|
|
353
|
+
</div>
|
|
354
|
+
<div class="community-feature">
|
|
355
|
+
<div class="feature-icon-small">⚡</div>
|
|
356
|
+
<div class="feature-text">
|
|
357
|
+
<h4>Quality Assurance</h4>
|
|
358
|
+
<p>Automated testing, validation, and documentation</p>
|
|
359
|
+
</div>
|
|
360
|
+
</div>
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
<div class="content-right">
|
|
364
|
+
<div class="tech-ecosystem">
|
|
365
|
+
<div class="ecosystem-center">
|
|
366
|
+
<div class="center-logo">🧠</div>
|
|
367
|
+
<span>Multi-Agent Engine</span>
|
|
368
|
+
</div>
|
|
369
|
+
<div class="ecosystem-ring">
|
|
370
|
+
<div class="ecosystem-item item-1">
|
|
371
|
+
<div class="item-icon">🎯</div>
|
|
372
|
+
<span>Central Orchestration</span>
|
|
373
|
+
</div>
|
|
374
|
+
<div class="ecosystem-item item-2">
|
|
375
|
+
<div class="item-icon">📝</div>
|
|
376
|
+
<span>Intent Understanding</span>
|
|
377
|
+
</div>
|
|
378
|
+
<div class="ecosystem-item item-3">
|
|
379
|
+
<div class="item-icon">🔍</div>
|
|
380
|
+
<span>Code Mining & Indexing</span>
|
|
381
|
+
</div>
|
|
382
|
+
<div class="ecosystem-item item-4">
|
|
383
|
+
<div class="item-icon">🧬</div>
|
|
384
|
+
<span>Code Generation</span>
|
|
385
|
+
</div>
|
|
386
|
+
</div>
|
|
387
|
+
</div>
|
|
388
|
+
</div>
|
|
389
|
+
</div>
|
|
390
|
+
</div>
|
|
391
|
+
""",
|
|
392
|
+
unsafe_allow_html=True,
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
def display_status(message: str, status_type: str = "info"):
|
|
397
|
+
"""
|
|
398
|
+
Display status message
|
|
399
|
+
|
|
400
|
+
Args:
|
|
401
|
+
message: Status message
|
|
402
|
+
status_type: Status type (success, error, warning, info)
|
|
403
|
+
"""
|
|
404
|
+
status_classes = {
|
|
405
|
+
"success": "status-success",
|
|
406
|
+
"error": "status-error",
|
|
407
|
+
"warning": "status-warning",
|
|
408
|
+
"info": "status-info",
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
icons = {"success": "✅", "error": "❌", "warning": "⚠️", "info": "ℹ️"}
|
|
412
|
+
|
|
413
|
+
css_class = status_classes.get(status_type, "status-info")
|
|
414
|
+
icon = icons.get(status_type, "ℹ️")
|
|
415
|
+
|
|
416
|
+
st.markdown(
|
|
417
|
+
f"""
|
|
418
|
+
<div class="{css_class}">
|
|
419
|
+
{icon} {message}
|
|
420
|
+
</div>
|
|
421
|
+
""",
|
|
422
|
+
unsafe_allow_html=True,
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
def system_status_component():
|
|
427
|
+
"""System status check component"""
|
|
428
|
+
st.markdown("### 🔧 System Status & Diagnostics")
|
|
429
|
+
|
|
430
|
+
# Basic system information
|
|
431
|
+
col1, col2 = st.columns(2)
|
|
432
|
+
|
|
433
|
+
with col1:
|
|
434
|
+
st.markdown("#### 📊 Environment")
|
|
435
|
+
st.info(f"**Python:** {sys.version.split()[0]}")
|
|
436
|
+
st.info(f"**Platform:** {sys.platform}")
|
|
437
|
+
|
|
438
|
+
# Check key modules
|
|
439
|
+
modules_to_check = [
|
|
440
|
+
("streamlit", "Streamlit UI Framework"),
|
|
441
|
+
("asyncio", "Async Processing"),
|
|
442
|
+
("nest_asyncio", "Nested Event Loops"),
|
|
443
|
+
("concurrent.futures", "Threading Support"),
|
|
444
|
+
]
|
|
445
|
+
|
|
446
|
+
st.markdown("#### 📦 Module Status")
|
|
447
|
+
for module_name, description in modules_to_check:
|
|
448
|
+
try:
|
|
449
|
+
__import__(module_name)
|
|
450
|
+
st.success(f"✅ {description}")
|
|
451
|
+
except ImportError:
|
|
452
|
+
st.error(f"❌ {description} - Missing")
|
|
453
|
+
|
|
454
|
+
with col2:
|
|
455
|
+
st.markdown("#### ⚙️ Threading & Context")
|
|
456
|
+
|
|
457
|
+
# Check Streamlit context
|
|
458
|
+
try:
|
|
459
|
+
from streamlit.runtime.scriptrunner import get_script_run_ctx
|
|
460
|
+
|
|
461
|
+
ctx = get_script_run_ctx()
|
|
462
|
+
if ctx:
|
|
463
|
+
st.success("✅ Streamlit Context Available")
|
|
464
|
+
else:
|
|
465
|
+
st.warning("⚠️ Streamlit Context Not Found")
|
|
466
|
+
except Exception as e:
|
|
467
|
+
st.error(f"❌ Context Check Failed: {e}")
|
|
468
|
+
|
|
469
|
+
# Check event loop
|
|
470
|
+
try:
|
|
471
|
+
import asyncio
|
|
472
|
+
|
|
473
|
+
try:
|
|
474
|
+
loop = asyncio.get_event_loop()
|
|
475
|
+
if loop.is_running():
|
|
476
|
+
st.info("🔄 Event Loop Running")
|
|
477
|
+
else:
|
|
478
|
+
st.info("⏸️ Event Loop Not Running")
|
|
479
|
+
except RuntimeError:
|
|
480
|
+
st.info("🆕 No Event Loop (Normal)")
|
|
481
|
+
except Exception as e:
|
|
482
|
+
st.error(f"❌ Event Loop Check Failed: {e}")
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
def error_troubleshooting_component():
|
|
486
|
+
"""Error troubleshooting component"""
|
|
487
|
+
with st.expander("🛠️ Troubleshooting Tips", expanded=False):
|
|
488
|
+
st.markdown("""
|
|
489
|
+
### Common Issues & Solutions
|
|
490
|
+
|
|
491
|
+
#### 1. ScriptRunContext Warnings
|
|
492
|
+
- **What it means:** Threading context warnings in Streamlit
|
|
493
|
+
- **Solution:** These warnings are usually safe to ignore
|
|
494
|
+
- **Prevention:** Restart the application if persistent
|
|
495
|
+
|
|
496
|
+
#### 2. Async Processing Errors
|
|
497
|
+
- **Symptoms:** "Event loop" or "Thread" errors
|
|
498
|
+
- **Solution:** The app uses multiple fallback methods
|
|
499
|
+
- **Action:** Try refreshing the page or restarting
|
|
500
|
+
|
|
501
|
+
#### 3. File Upload Issues
|
|
502
|
+
- **Check:** File size < 200MB
|
|
503
|
+
- **Formats:** PDF, DOCX, TXT, HTML, MD
|
|
504
|
+
- **Action:** Try a different file format
|
|
505
|
+
|
|
506
|
+
#### 4. Processing Timeout
|
|
507
|
+
- **Normal:** Large papers may take 5-10 minutes
|
|
508
|
+
- **Action:** Wait patiently, check progress indicators
|
|
509
|
+
- **Limit:** 5-minute maximum processing time
|
|
510
|
+
|
|
511
|
+
#### 5. Memory Issues
|
|
512
|
+
- **Symptoms:** "Out of memory" errors
|
|
513
|
+
- **Solution:** Close other applications
|
|
514
|
+
- **Action:** Try smaller/simpler papers first
|
|
515
|
+
""")
|
|
516
|
+
|
|
517
|
+
if st.button("🔄 Reset Application State"):
|
|
518
|
+
# Clear all session state
|
|
519
|
+
for key in list(st.session_state.keys()):
|
|
520
|
+
del st.session_state[key]
|
|
521
|
+
st.success("Application state reset! Please refresh the page.")
|
|
522
|
+
st.rerun()
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
def sidebar_control_panel() -> Dict[str, Any]:
|
|
526
|
+
"""
|
|
527
|
+
Sidebar control panel
|
|
528
|
+
|
|
529
|
+
Returns:
|
|
530
|
+
Control panel state
|
|
531
|
+
"""
|
|
532
|
+
with st.sidebar:
|
|
533
|
+
st.markdown("### 🎛️ Control Panel")
|
|
534
|
+
|
|
535
|
+
# Application status
|
|
536
|
+
if st.session_state.processing:
|
|
537
|
+
st.warning("🟡 Engine Processing...")
|
|
538
|
+
else:
|
|
539
|
+
st.info("⚪ Engine Ready")
|
|
540
|
+
|
|
541
|
+
# Workflow configuration options
|
|
542
|
+
st.markdown("### ⚙️ Workflow Settings")
|
|
543
|
+
|
|
544
|
+
# Indexing functionality toggle
|
|
545
|
+
enable_indexing = st.checkbox(
|
|
546
|
+
"🗂️ Enable Codebase Indexing",
|
|
547
|
+
value=True,
|
|
548
|
+
help="Enable GitHub repository download and codebase indexing. Disabling this will skip Phase 6 (GitHub Download) and Phase 7 (Codebase Indexing) for faster processing.",
|
|
549
|
+
key="enable_indexing",
|
|
550
|
+
)
|
|
551
|
+
|
|
552
|
+
if enable_indexing:
|
|
553
|
+
st.success("✅ Full workflow with indexing enabled")
|
|
554
|
+
else:
|
|
555
|
+
st.info("⚡ Fast mode - indexing disabled")
|
|
556
|
+
|
|
557
|
+
# System information
|
|
558
|
+
st.markdown("### 📊 System Info")
|
|
559
|
+
st.info(f"**Python:** {sys.version.split()[0]}")
|
|
560
|
+
st.info(f"**Platform:** {sys.platform}")
|
|
561
|
+
|
|
562
|
+
# Add system status check
|
|
563
|
+
with st.expander("🔧 System Status"):
|
|
564
|
+
system_status_component()
|
|
565
|
+
|
|
566
|
+
# Add error diagnostics
|
|
567
|
+
error_troubleshooting_component()
|
|
568
|
+
|
|
569
|
+
st.markdown("---")
|
|
570
|
+
|
|
571
|
+
# Processing history
|
|
572
|
+
history_info = display_processing_history()
|
|
573
|
+
|
|
574
|
+
return {
|
|
575
|
+
"processing": st.session_state.processing,
|
|
576
|
+
"history_count": history_info["count"],
|
|
577
|
+
"has_history": history_info["has_history"],
|
|
578
|
+
"enable_indexing": enable_indexing, # Add indexing toggle state
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
def display_processing_history() -> Dict[str, Any]:
|
|
583
|
+
"""
|
|
584
|
+
Display processing history
|
|
585
|
+
|
|
586
|
+
Returns:
|
|
587
|
+
History information
|
|
588
|
+
"""
|
|
589
|
+
st.markdown("### 📊 Processing History")
|
|
590
|
+
|
|
591
|
+
has_history = bool(st.session_state.results)
|
|
592
|
+
history_count = len(st.session_state.results)
|
|
593
|
+
|
|
594
|
+
if has_history:
|
|
595
|
+
# Only show last 10 records
|
|
596
|
+
recent_results = st.session_state.results[-10:]
|
|
597
|
+
for i, result in enumerate(reversed(recent_results)):
|
|
598
|
+
status_icon = "✅" if result.get("status") == "success" else "❌"
|
|
599
|
+
with st.expander(
|
|
600
|
+
f"{status_icon} Task - {result.get('timestamp', 'Unknown')}"
|
|
601
|
+
):
|
|
602
|
+
st.write(f"**Status:** {result.get('status', 'Unknown')}")
|
|
603
|
+
if result.get("input_type"):
|
|
604
|
+
st.write(f"**Type:** {result['input_type']}")
|
|
605
|
+
if result.get("error"):
|
|
606
|
+
st.error(f"Error: {result['error']}")
|
|
607
|
+
else:
|
|
608
|
+
st.info("No processing history yet")
|
|
609
|
+
|
|
610
|
+
# Clear history button
|
|
611
|
+
if has_history:
|
|
612
|
+
col1, col2 = st.columns(2)
|
|
613
|
+
with col1:
|
|
614
|
+
if st.button("🗑️ Clear History", use_container_width=True):
|
|
615
|
+
st.session_state.results = []
|
|
616
|
+
st.rerun()
|
|
617
|
+
with col2:
|
|
618
|
+
st.info(f"Total: {history_count} tasks")
|
|
619
|
+
|
|
620
|
+
return {"has_history": has_history, "count": history_count}
|
|
621
|
+
|
|
622
|
+
|
|
623
|
+
def file_input_component(task_counter: int) -> Optional[str]:
|
|
624
|
+
"""
|
|
625
|
+
File input component with automatic PDF conversion
|
|
626
|
+
|
|
627
|
+
Args:
|
|
628
|
+
task_counter: Task counter
|
|
629
|
+
|
|
630
|
+
Returns:
|
|
631
|
+
PDF file path or None
|
|
632
|
+
"""
|
|
633
|
+
uploaded_file = st.file_uploader(
|
|
634
|
+
"Upload research paper file",
|
|
635
|
+
type=[
|
|
636
|
+
"pdf",
|
|
637
|
+
"docx",
|
|
638
|
+
"doc",
|
|
639
|
+
"ppt",
|
|
640
|
+
"pptx",
|
|
641
|
+
"xls",
|
|
642
|
+
"xlsx",
|
|
643
|
+
"html",
|
|
644
|
+
"htm",
|
|
645
|
+
"txt",
|
|
646
|
+
"md",
|
|
647
|
+
],
|
|
648
|
+
help="Supported formats: PDF, Word, PowerPoint, Excel, HTML, Text (all files will be converted to PDF)",
|
|
649
|
+
key=f"file_uploader_{task_counter}",
|
|
650
|
+
)
|
|
651
|
+
|
|
652
|
+
if uploaded_file is not None:
|
|
653
|
+
# Display file information
|
|
654
|
+
file_size = len(uploaded_file.getvalue())
|
|
655
|
+
st.info(f"📄 **File:** {uploaded_file.name} ({format_file_size(file_size)})")
|
|
656
|
+
|
|
657
|
+
# Save uploaded file to temporary directory
|
|
658
|
+
try:
|
|
659
|
+
import tempfile
|
|
660
|
+
import sys
|
|
661
|
+
import os
|
|
662
|
+
from pathlib import Path
|
|
663
|
+
|
|
664
|
+
# Add project root to path for imports
|
|
665
|
+
current_dir = Path(__file__).parent
|
|
666
|
+
project_root = current_dir.parent
|
|
667
|
+
if str(project_root) not in sys.path:
|
|
668
|
+
sys.path.insert(0, str(project_root))
|
|
669
|
+
|
|
670
|
+
# Import PDF converter
|
|
671
|
+
from tools.pdf_converter import PDFConverter
|
|
672
|
+
|
|
673
|
+
# Save original file
|
|
674
|
+
file_ext = uploaded_file.name.split(".")[-1].lower()
|
|
675
|
+
with tempfile.NamedTemporaryFile(
|
|
676
|
+
delete=False, suffix=f".{file_ext}"
|
|
677
|
+
) as tmp_file:
|
|
678
|
+
tmp_file.write(uploaded_file.getvalue())
|
|
679
|
+
original_file_path = tmp_file.name
|
|
680
|
+
|
|
681
|
+
st.success("✅ File uploaded successfully!")
|
|
682
|
+
|
|
683
|
+
# Check if file is already PDF
|
|
684
|
+
if file_ext == "pdf":
|
|
685
|
+
st.info("📑 File is already in PDF format, no conversion needed.")
|
|
686
|
+
return original_file_path
|
|
687
|
+
|
|
688
|
+
# Convert to PDF
|
|
689
|
+
with st.spinner(f"🔄 Converting {file_ext.upper()} to PDF..."):
|
|
690
|
+
try:
|
|
691
|
+
converter = PDFConverter()
|
|
692
|
+
|
|
693
|
+
# Check dependencies
|
|
694
|
+
deps = converter.check_dependencies()
|
|
695
|
+
missing_deps = []
|
|
696
|
+
|
|
697
|
+
if (
|
|
698
|
+
file_ext in {"doc", "docx", "ppt", "pptx", "xls", "xlsx"}
|
|
699
|
+
and not deps["libreoffice"]
|
|
700
|
+
):
|
|
701
|
+
missing_deps.append("LibreOffice")
|
|
702
|
+
|
|
703
|
+
if file_ext in {"txt", "md"} and not deps["reportlab"]:
|
|
704
|
+
missing_deps.append("ReportLab")
|
|
705
|
+
|
|
706
|
+
if missing_deps:
|
|
707
|
+
st.error(f"❌ Missing dependencies: {', '.join(missing_deps)}")
|
|
708
|
+
st.info("💡 Please install the required dependencies:")
|
|
709
|
+
if "LibreOffice" in missing_deps:
|
|
710
|
+
st.code(
|
|
711
|
+
"# Install LibreOffice\n"
|
|
712
|
+
"# Windows: Download from https://www.libreoffice.org/\n"
|
|
713
|
+
"# macOS: brew install --cask libreoffice\n"
|
|
714
|
+
"# Ubuntu: sudo apt-get install libreoffice"
|
|
715
|
+
)
|
|
716
|
+
if "ReportLab" in missing_deps:
|
|
717
|
+
st.code("pip install reportlab")
|
|
718
|
+
|
|
719
|
+
# Clean up original file
|
|
720
|
+
try:
|
|
721
|
+
os.unlink(original_file_path)
|
|
722
|
+
except Exception:
|
|
723
|
+
pass
|
|
724
|
+
return None
|
|
725
|
+
|
|
726
|
+
# Perform conversion
|
|
727
|
+
pdf_path = converter.convert_to_pdf(original_file_path)
|
|
728
|
+
|
|
729
|
+
# Clean up original file
|
|
730
|
+
try:
|
|
731
|
+
os.unlink(original_file_path)
|
|
732
|
+
except Exception:
|
|
733
|
+
pass
|
|
734
|
+
|
|
735
|
+
# Display conversion result
|
|
736
|
+
pdf_size = Path(pdf_path).stat().st_size
|
|
737
|
+
st.success("✅ Successfully converted to PDF!")
|
|
738
|
+
st.info(
|
|
739
|
+
f"📑 **PDF File:** {Path(pdf_path).name} ({format_file_size(pdf_size)})"
|
|
740
|
+
)
|
|
741
|
+
|
|
742
|
+
return str(pdf_path)
|
|
743
|
+
|
|
744
|
+
except Exception as e:
|
|
745
|
+
st.error(f"❌ PDF conversion failed: {str(e)}")
|
|
746
|
+
st.warning("💡 You can try:")
|
|
747
|
+
st.markdown("- Converting the file to PDF manually")
|
|
748
|
+
st.markdown("- Using a different file format")
|
|
749
|
+
st.markdown("- Checking if the file is corrupted")
|
|
750
|
+
|
|
751
|
+
# Clean up original file
|
|
752
|
+
try:
|
|
753
|
+
os.unlink(original_file_path)
|
|
754
|
+
except Exception:
|
|
755
|
+
pass
|
|
756
|
+
return None
|
|
757
|
+
|
|
758
|
+
except Exception as e:
|
|
759
|
+
st.error(f"❌ Failed to process uploaded file: {str(e)}")
|
|
760
|
+
return None
|
|
761
|
+
|
|
762
|
+
return None
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
def url_input_component(task_counter: int) -> Optional[str]:
|
|
766
|
+
"""
|
|
767
|
+
URL input component
|
|
768
|
+
|
|
769
|
+
Args:
|
|
770
|
+
task_counter: Task counter
|
|
771
|
+
|
|
772
|
+
Returns:
|
|
773
|
+
URL or None
|
|
774
|
+
"""
|
|
775
|
+
url_input = st.text_input(
|
|
776
|
+
"Enter paper URL",
|
|
777
|
+
placeholder="https://arxiv.org/abs/..., https://ieeexplore.ieee.org/..., etc.",
|
|
778
|
+
help="Enter a direct link to a research paper (arXiv, IEEE, ACM, etc.)",
|
|
779
|
+
key=f"url_input_{task_counter}",
|
|
780
|
+
)
|
|
781
|
+
|
|
782
|
+
if url_input:
|
|
783
|
+
# Simple URL validation
|
|
784
|
+
if url_input.startswith(("http://", "https://")):
|
|
785
|
+
st.success(f"✅ URL entered: {url_input}")
|
|
786
|
+
return url_input
|
|
787
|
+
else:
|
|
788
|
+
st.warning("⚠️ Please enter a valid URL starting with http:// or https://")
|
|
789
|
+
return None
|
|
790
|
+
|
|
791
|
+
return None
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
def chat_input_component(task_counter: int) -> Optional[str]:
|
|
795
|
+
"""
|
|
796
|
+
Chat input component for coding requirements
|
|
797
|
+
|
|
798
|
+
Args:
|
|
799
|
+
task_counter: Task counter
|
|
800
|
+
|
|
801
|
+
Returns:
|
|
802
|
+
User coding requirements or None
|
|
803
|
+
"""
|
|
804
|
+
st.markdown(
|
|
805
|
+
"""
|
|
806
|
+
<div style="background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
|
|
807
|
+
border-radius: 10px;
|
|
808
|
+
padding: 15px;
|
|
809
|
+
margin-bottom: 20px;
|
|
810
|
+
border-left: 4px solid #4dd0e1;">
|
|
811
|
+
<h4 style="color: white; margin: 0 0 10px 0; font-size: 1.1rem;">
|
|
812
|
+
💬 Describe Your Coding Requirements
|
|
813
|
+
</h4>
|
|
814
|
+
<p style="color: #e0f7fa; margin: 0; font-size: 0.9rem;">
|
|
815
|
+
Tell us what you want to build. Our AI will analyze your requirements and generate a comprehensive implementation plan.
|
|
816
|
+
</p>
|
|
817
|
+
</div>
|
|
818
|
+
""",
|
|
819
|
+
unsafe_allow_html=True,
|
|
820
|
+
)
|
|
821
|
+
|
|
822
|
+
# Examples to help users understand what they can input
|
|
823
|
+
with st.expander("💡 See Examples", expanded=False):
|
|
824
|
+
st.markdown("""
|
|
825
|
+
**Academic Research Examples:**
|
|
826
|
+
- "I need to implement a reinforcement learning algorithm for robotic control"
|
|
827
|
+
- "Create a neural network for image classification with attention mechanisms"
|
|
828
|
+
- "Build a natural language processing pipeline for sentiment analysis"
|
|
829
|
+
|
|
830
|
+
**Engineering Project Examples:**
|
|
831
|
+
- "Develop a web application for project management with user authentication"
|
|
832
|
+
- "Create a data visualization dashboard for sales analytics"
|
|
833
|
+
- "Build a REST API for a e-commerce platform with database integration"
|
|
834
|
+
|
|
835
|
+
**Mixed Project Examples:**
|
|
836
|
+
- "Implement a machine learning model with a web interface for real-time predictions"
|
|
837
|
+
- "Create a research tool with user-friendly GUI for data analysis"
|
|
838
|
+
- "Build a chatbot with both academic evaluation metrics and production deployment"
|
|
839
|
+
""")
|
|
840
|
+
|
|
841
|
+
# Main text area for user input
|
|
842
|
+
user_input = st.text_area(
|
|
843
|
+
"Enter your coding requirements:",
|
|
844
|
+
placeholder="""Example: I want to build a web application that can analyze user sentiment from social media posts. The application should have:
|
|
845
|
+
|
|
846
|
+
1. A user-friendly interface where users can input text or upload files
|
|
847
|
+
2. A machine learning backend that performs sentiment analysis
|
|
848
|
+
3. Visualization of results with charts and statistics
|
|
849
|
+
4. User authentication and data storage
|
|
850
|
+
5. REST API for integration with other applications
|
|
851
|
+
|
|
852
|
+
The system should be scalable and production-ready, with proper error handling and documentation.""",
|
|
853
|
+
height=200,
|
|
854
|
+
help="Describe what you want to build, including functionality, technologies, and any specific requirements",
|
|
855
|
+
key=f"chat_input_{task_counter}",
|
|
856
|
+
)
|
|
857
|
+
|
|
858
|
+
if user_input and len(user_input.strip()) > 20: # Minimum length check
|
|
859
|
+
# Display input summary
|
|
860
|
+
word_count = len(user_input.split())
|
|
861
|
+
char_count = len(user_input)
|
|
862
|
+
|
|
863
|
+
st.success(
|
|
864
|
+
f"✅ **Requirements captured!** ({word_count} words, {char_count} characters)"
|
|
865
|
+
)
|
|
866
|
+
|
|
867
|
+
# Show a preview of what will be analyzed
|
|
868
|
+
with st.expander("📋 Preview your requirements", expanded=False):
|
|
869
|
+
st.text_area(
|
|
870
|
+
"Your input:",
|
|
871
|
+
user_input,
|
|
872
|
+
height=100,
|
|
873
|
+
disabled=True,
|
|
874
|
+
key=f"preview_{task_counter}",
|
|
875
|
+
)
|
|
876
|
+
|
|
877
|
+
return user_input.strip()
|
|
878
|
+
|
|
879
|
+
elif user_input and len(user_input.strip()) <= 20:
|
|
880
|
+
st.warning(
|
|
881
|
+
"⚠️ Please provide more detailed requirements (at least 20 characters)"
|
|
882
|
+
)
|
|
883
|
+
return None
|
|
884
|
+
|
|
885
|
+
return None
|
|
886
|
+
|
|
887
|
+
|
|
888
|
+
def input_method_selector(task_counter: int) -> tuple[Optional[str], Optional[str]]:
|
|
889
|
+
"""
|
|
890
|
+
Input method selector
|
|
891
|
+
|
|
892
|
+
Args:
|
|
893
|
+
task_counter: Task counter
|
|
894
|
+
|
|
895
|
+
Returns:
|
|
896
|
+
(input_source, input_type)
|
|
897
|
+
"""
|
|
898
|
+
st.markdown(
|
|
899
|
+
"""
|
|
900
|
+
<h3 style="color: var(--text-primary) !important; font-family: 'Inter', sans-serif !important; font-weight: 600 !important; font-size: 1.5rem !important; margin-bottom: 1rem !important;">
|
|
901
|
+
🚀 Start Processing
|
|
902
|
+
</h3>
|
|
903
|
+
""",
|
|
904
|
+
unsafe_allow_html=True,
|
|
905
|
+
)
|
|
906
|
+
|
|
907
|
+
# Input options
|
|
908
|
+
st.markdown(
|
|
909
|
+
"""
|
|
910
|
+
<p style="color: var(--text-secondary) !important; font-family: 'Inter', sans-serif !important; font-weight: 500 !important; margin-bottom: 1rem !important;">
|
|
911
|
+
Choose input method:
|
|
912
|
+
</p>
|
|
913
|
+
""",
|
|
914
|
+
unsafe_allow_html=True,
|
|
915
|
+
)
|
|
916
|
+
|
|
917
|
+
input_method = st.radio(
|
|
918
|
+
"Choose your input method:",
|
|
919
|
+
["📁 Upload File", "🌐 Enter URL", "💬 Chat Input"],
|
|
920
|
+
horizontal=True,
|
|
921
|
+
label_visibility="hidden",
|
|
922
|
+
key=f"input_method_{task_counter}",
|
|
923
|
+
)
|
|
924
|
+
|
|
925
|
+
input_source = None
|
|
926
|
+
input_type = None
|
|
927
|
+
|
|
928
|
+
if input_method == "📁 Upload File":
|
|
929
|
+
input_source = file_input_component(task_counter)
|
|
930
|
+
input_type = "file" if input_source else None
|
|
931
|
+
elif input_method == "🌐 Enter URL":
|
|
932
|
+
input_source = url_input_component(task_counter)
|
|
933
|
+
input_type = "url" if input_source else None
|
|
934
|
+
else: # Chat input
|
|
935
|
+
input_source = chat_input_component(task_counter)
|
|
936
|
+
input_type = "chat" if input_source else None
|
|
937
|
+
|
|
938
|
+
return input_source, input_type
|
|
939
|
+
|
|
940
|
+
|
|
941
|
+
def results_display_component(result: Dict[str, Any], task_counter: int):
|
|
942
|
+
"""
|
|
943
|
+
Results display component
|
|
944
|
+
|
|
945
|
+
Args:
|
|
946
|
+
result: Processing result
|
|
947
|
+
task_counter: Task counter
|
|
948
|
+
"""
|
|
949
|
+
st.markdown("### 📋 Processing Results")
|
|
950
|
+
|
|
951
|
+
# Display overall status
|
|
952
|
+
if result.get("status") == "success":
|
|
953
|
+
st.success("🎉 **All workflows completed successfully!**")
|
|
954
|
+
else:
|
|
955
|
+
st.error("❌ **Processing encountered errors**")
|
|
956
|
+
|
|
957
|
+
# Create tabs to organize different phase results
|
|
958
|
+
tab1, tab2, tab3, tab4 = st.tabs(
|
|
959
|
+
[
|
|
960
|
+
"📊 Analysis Phase",
|
|
961
|
+
"📥 Download Phase",
|
|
962
|
+
"🔧 Implementation Phase",
|
|
963
|
+
"📁 Generated Files",
|
|
964
|
+
]
|
|
965
|
+
)
|
|
966
|
+
|
|
967
|
+
with tab1:
|
|
968
|
+
st.markdown("#### 📊 Paper Analysis Results")
|
|
969
|
+
with st.expander("Analysis Output Details", expanded=True):
|
|
970
|
+
analysis_result = result.get(
|
|
971
|
+
"analysis_result", "No analysis result available"
|
|
972
|
+
)
|
|
973
|
+
try:
|
|
974
|
+
# Try to parse JSON result for formatted display
|
|
975
|
+
if analysis_result.strip().startswith("{"):
|
|
976
|
+
parsed_analysis = json.loads(analysis_result)
|
|
977
|
+
st.json(parsed_analysis)
|
|
978
|
+
else:
|
|
979
|
+
st.text_area(
|
|
980
|
+
"Raw Analysis Output",
|
|
981
|
+
analysis_result,
|
|
982
|
+
height=300,
|
|
983
|
+
key=f"analysis_{task_counter}",
|
|
984
|
+
)
|
|
985
|
+
except Exception:
|
|
986
|
+
st.text_area(
|
|
987
|
+
"Analysis Output",
|
|
988
|
+
analysis_result,
|
|
989
|
+
height=300,
|
|
990
|
+
key=f"analysis_{task_counter}",
|
|
991
|
+
)
|
|
992
|
+
|
|
993
|
+
with tab2:
|
|
994
|
+
st.markdown("#### 📥 Download & Preparation Results")
|
|
995
|
+
with st.expander("Download Process Details", expanded=True):
|
|
996
|
+
download_result = result.get(
|
|
997
|
+
"download_result", "No download result available"
|
|
998
|
+
)
|
|
999
|
+
st.text_area(
|
|
1000
|
+
"Download Output",
|
|
1001
|
+
download_result,
|
|
1002
|
+
height=300,
|
|
1003
|
+
key=f"download_{task_counter}",
|
|
1004
|
+
)
|
|
1005
|
+
|
|
1006
|
+
# Try to extract file path information
|
|
1007
|
+
if "paper_dir" in download_result or "path" in download_result.lower():
|
|
1008
|
+
st.info(
|
|
1009
|
+
"💡 **Tip:** Look for file paths in the output above to locate generated files"
|
|
1010
|
+
)
|
|
1011
|
+
|
|
1012
|
+
with tab3:
|
|
1013
|
+
st.markdown("#### 🔧 Code Implementation Results")
|
|
1014
|
+
repo_result = result.get("repo_result", "No implementation result available")
|
|
1015
|
+
|
|
1016
|
+
# Analyze implementation results to extract key information
|
|
1017
|
+
if "successfully" in repo_result.lower():
|
|
1018
|
+
st.success("✅ Code implementation completed successfully!")
|
|
1019
|
+
elif "failed" in repo_result.lower():
|
|
1020
|
+
st.warning("⚠️ Code implementation encountered issues")
|
|
1021
|
+
else:
|
|
1022
|
+
st.info("ℹ️ Code implementation status unclear")
|
|
1023
|
+
|
|
1024
|
+
with st.expander("Implementation Details", expanded=True):
|
|
1025
|
+
st.text_area(
|
|
1026
|
+
"Repository & Code Generation Output",
|
|
1027
|
+
repo_result,
|
|
1028
|
+
height=300,
|
|
1029
|
+
key=f"repo_{task_counter}",
|
|
1030
|
+
)
|
|
1031
|
+
|
|
1032
|
+
# Try to extract generated code directory information
|
|
1033
|
+
if "Code generated in:" in repo_result:
|
|
1034
|
+
code_dir = repo_result.split("Code generated in:")[-1].strip()
|
|
1035
|
+
st.markdown(f"**📁 Generated Code Directory:** `{code_dir}`")
|
|
1036
|
+
|
|
1037
|
+
# Display workflow stage details
|
|
1038
|
+
st.markdown("#### 🔄 Workflow Stages Completed")
|
|
1039
|
+
stages = [
|
|
1040
|
+
("📄 Document Processing", "✅"),
|
|
1041
|
+
("🔍 Reference Analysis", "✅"),
|
|
1042
|
+
("📋 Plan Generation", "✅"),
|
|
1043
|
+
("📦 Repository Download", "✅"),
|
|
1044
|
+
("🗂️ Codebase Indexing", "✅" if "indexing" in repo_result.lower() else "⚠️"),
|
|
1045
|
+
(
|
|
1046
|
+
"⚙️ Code Implementation",
|
|
1047
|
+
"✅" if "successfully" in repo_result.lower() else "⚠️",
|
|
1048
|
+
),
|
|
1049
|
+
]
|
|
1050
|
+
|
|
1051
|
+
for stage_name, status in stages:
|
|
1052
|
+
st.markdown(f"- {stage_name}: {status}")
|
|
1053
|
+
|
|
1054
|
+
with tab4:
|
|
1055
|
+
st.markdown("#### 📁 Generated Files & Reports")
|
|
1056
|
+
|
|
1057
|
+
# Try to extract file paths from results
|
|
1058
|
+
all_results = (
|
|
1059
|
+
f"{result.get('download_result', '')} {result.get('repo_result', '')}"
|
|
1060
|
+
)
|
|
1061
|
+
|
|
1062
|
+
# Look for possible file path patterns
|
|
1063
|
+
import re
|
|
1064
|
+
|
|
1065
|
+
file_patterns = [
|
|
1066
|
+
r"([^\s]+\.txt)",
|
|
1067
|
+
r"([^\s]+\.json)",
|
|
1068
|
+
r"([^\s]+\.py)",
|
|
1069
|
+
r"([^\s]+\.md)",
|
|
1070
|
+
r"paper_dir[:\s]+([^\s]+)",
|
|
1071
|
+
r"saved to ([^\s]+)",
|
|
1072
|
+
r"generated in[:\s]+([^\s]+)",
|
|
1073
|
+
]
|
|
1074
|
+
|
|
1075
|
+
found_files = set()
|
|
1076
|
+
for pattern in file_patterns:
|
|
1077
|
+
matches = re.findall(pattern, all_results, re.IGNORECASE)
|
|
1078
|
+
for match in matches:
|
|
1079
|
+
if isinstance(match, tuple):
|
|
1080
|
+
found_files.update(match)
|
|
1081
|
+
else:
|
|
1082
|
+
found_files.add(match)
|
|
1083
|
+
|
|
1084
|
+
if found_files:
|
|
1085
|
+
st.markdown("**📄 Detected Generated Files:**")
|
|
1086
|
+
for file_path in sorted(found_files):
|
|
1087
|
+
if file_path and len(file_path) > 3: # Filter out too short matches
|
|
1088
|
+
st.markdown(f"- `{file_path}`")
|
|
1089
|
+
else:
|
|
1090
|
+
st.info(
|
|
1091
|
+
"No specific file paths detected in the output. Check the detailed results above for file locations."
|
|
1092
|
+
)
|
|
1093
|
+
|
|
1094
|
+
# Provide option to view raw results
|
|
1095
|
+
with st.expander("View Raw Processing Results"):
|
|
1096
|
+
st.json(
|
|
1097
|
+
{
|
|
1098
|
+
"analysis_result": result.get("analysis_result", ""),
|
|
1099
|
+
"download_result": result.get("download_result", ""),
|
|
1100
|
+
"repo_result": result.get("repo_result", ""),
|
|
1101
|
+
"status": result.get("status", "unknown"),
|
|
1102
|
+
}
|
|
1103
|
+
)
|
|
1104
|
+
|
|
1105
|
+
# Action buttons
|
|
1106
|
+
st.markdown("---")
|
|
1107
|
+
col1, col2 = st.columns(2)
|
|
1108
|
+
|
|
1109
|
+
with col1:
|
|
1110
|
+
if st.button("🔄 Process New Paper", type="primary", use_container_width=True):
|
|
1111
|
+
st.session_state.show_results = False
|
|
1112
|
+
st.session_state.last_result = None
|
|
1113
|
+
st.session_state.last_error = None
|
|
1114
|
+
st.session_state.task_counter += 1
|
|
1115
|
+
st.rerun()
|
|
1116
|
+
|
|
1117
|
+
with col2:
|
|
1118
|
+
if st.button("💾 Export Results", type="secondary", use_container_width=True):
|
|
1119
|
+
# Create result export
|
|
1120
|
+
export_data = {
|
|
1121
|
+
"timestamp": datetime.now().isoformat(),
|
|
1122
|
+
"processing_results": result,
|
|
1123
|
+
"status": result.get("status", "unknown"),
|
|
1124
|
+
}
|
|
1125
|
+
st.download_button(
|
|
1126
|
+
label="📄 Download Results JSON",
|
|
1127
|
+
data=json.dumps(export_data, indent=2, ensure_ascii=False),
|
|
1128
|
+
file_name=f"paper_processing_results_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
|
|
1129
|
+
mime="application/json",
|
|
1130
|
+
use_container_width=True,
|
|
1131
|
+
)
|
|
1132
|
+
|
|
1133
|
+
|
|
1134
|
+
def progress_display_component():
|
|
1135
|
+
"""
|
|
1136
|
+
Progress display component
|
|
1137
|
+
|
|
1138
|
+
Returns:
|
|
1139
|
+
(progress_bar, status_text)
|
|
1140
|
+
"""
|
|
1141
|
+
# Display processing progress title
|
|
1142
|
+
st.markdown("### 📊 Processing Progress")
|
|
1143
|
+
|
|
1144
|
+
# Create progress container
|
|
1145
|
+
progress_container = st.container()
|
|
1146
|
+
|
|
1147
|
+
with progress_container:
|
|
1148
|
+
# Add custom CSS styles
|
|
1149
|
+
st.markdown(
|
|
1150
|
+
"""
|
|
1151
|
+
<style>
|
|
1152
|
+
.progress-container {
|
|
1153
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
1154
|
+
border-radius: 15px;
|
|
1155
|
+
padding: 20px;
|
|
1156
|
+
margin: 10px 0;
|
|
1157
|
+
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
|
|
1158
|
+
}
|
|
1159
|
+
.progress-steps {
|
|
1160
|
+
display: flex;
|
|
1161
|
+
justify-content: space-between;
|
|
1162
|
+
margin-bottom: 15px;
|
|
1163
|
+
flex-wrap: wrap;
|
|
1164
|
+
}
|
|
1165
|
+
.progress-step {
|
|
1166
|
+
background: rgba(255,255,255,0.1);
|
|
1167
|
+
border-radius: 10px;
|
|
1168
|
+
padding: 8px 12px;
|
|
1169
|
+
margin: 2px;
|
|
1170
|
+
color: white;
|
|
1171
|
+
font-size: 0.8rem;
|
|
1172
|
+
font-weight: 500;
|
|
1173
|
+
border: 2px solid transparent;
|
|
1174
|
+
transition: all 0.3s ease;
|
|
1175
|
+
}
|
|
1176
|
+
.progress-step.active {
|
|
1177
|
+
background: rgba(255,255,255,0.3);
|
|
1178
|
+
border-color: #00ff88;
|
|
1179
|
+
box-shadow: 0 0 15px rgba(0,255,136,0.3);
|
|
1180
|
+
}
|
|
1181
|
+
.progress-step.completed {
|
|
1182
|
+
background: rgba(0,255,136,0.2);
|
|
1183
|
+
border-color: #00ff88;
|
|
1184
|
+
}
|
|
1185
|
+
.status-text {
|
|
1186
|
+
color: white;
|
|
1187
|
+
font-weight: 600;
|
|
1188
|
+
font-size: 1.1rem;
|
|
1189
|
+
margin: 10px 0;
|
|
1190
|
+
text-align: center;
|
|
1191
|
+
}
|
|
1192
|
+
</style>
|
|
1193
|
+
""",
|
|
1194
|
+
unsafe_allow_html=True,
|
|
1195
|
+
)
|
|
1196
|
+
|
|
1197
|
+
st.markdown('<div class="progress-container">', unsafe_allow_html=True)
|
|
1198
|
+
|
|
1199
|
+
# Create step indicator
|
|
1200
|
+
st.markdown(
|
|
1201
|
+
"""
|
|
1202
|
+
<div class="progress-steps">
|
|
1203
|
+
<div class="progress-step" id="step-init">🚀 Initialize</div>
|
|
1204
|
+
<div class="progress-step" id="step-analyze">📊 Analyze</div>
|
|
1205
|
+
<div class="progress-step" id="step-download">📥 Download</div>
|
|
1206
|
+
<div class="progress-step" id="step-references">🔍 References</div>
|
|
1207
|
+
<div class="progress-step" id="step-plan">📋 Plan</div>
|
|
1208
|
+
<div class="progress-step" id="step-repos">📦 Repos</div>
|
|
1209
|
+
<div class="progress-step" id="step-index">🗂️ Index</div>
|
|
1210
|
+
<div class="progress-step" id="step-implement">⚙️ Implement</div>
|
|
1211
|
+
</div>
|
|
1212
|
+
""",
|
|
1213
|
+
unsafe_allow_html=True,
|
|
1214
|
+
)
|
|
1215
|
+
|
|
1216
|
+
# Create progress bar and status text
|
|
1217
|
+
progress_bar = st.progress(0)
|
|
1218
|
+
status_text = st.empty()
|
|
1219
|
+
|
|
1220
|
+
st.markdown("</div>", unsafe_allow_html=True)
|
|
1221
|
+
|
|
1222
|
+
return progress_bar, status_text
|
|
1223
|
+
|
|
1224
|
+
|
|
1225
|
+
def enhanced_progress_display_component(
|
|
1226
|
+
enable_indexing: bool = True, chat_mode: bool = False
|
|
1227
|
+
):
|
|
1228
|
+
"""
|
|
1229
|
+
Enhanced progress display component
|
|
1230
|
+
|
|
1231
|
+
Args:
|
|
1232
|
+
enable_indexing: Whether indexing is enabled
|
|
1233
|
+
chat_mode: Whether in chat mode (user requirements input)
|
|
1234
|
+
|
|
1235
|
+
Returns:
|
|
1236
|
+
(progress_bar, status_text, step_indicator, workflow_steps)
|
|
1237
|
+
"""
|
|
1238
|
+
# Display processing progress title
|
|
1239
|
+
if chat_mode:
|
|
1240
|
+
st.markdown("### 💬 AI Chat Planning - Requirements to Code Workflow")
|
|
1241
|
+
elif enable_indexing:
|
|
1242
|
+
st.markdown("### 🚀 AI Research Engine - Full Processing Workflow")
|
|
1243
|
+
else:
|
|
1244
|
+
st.markdown(
|
|
1245
|
+
"### ⚡ AI Research Engine - Fast Processing Workflow (Indexing Disabled)"
|
|
1246
|
+
)
|
|
1247
|
+
|
|
1248
|
+
# Create progress container
|
|
1249
|
+
progress_container = st.container()
|
|
1250
|
+
|
|
1251
|
+
with progress_container:
|
|
1252
|
+
# Workflow step definitions - adjust based on mode and indexing toggle
|
|
1253
|
+
if chat_mode:
|
|
1254
|
+
# Chat mode - simplified workflow for user requirements
|
|
1255
|
+
workflow_steps = [
|
|
1256
|
+
("🚀", "Initialize", "Setting up chat engine"),
|
|
1257
|
+
("💬", "Planning", "Analyzing requirements"),
|
|
1258
|
+
("🏗️", "Setup", "Creating workspace"),
|
|
1259
|
+
("📝", "Save Plan", "Saving implementation plan"),
|
|
1260
|
+
("⚙️", "Implement", "Generating code"),
|
|
1261
|
+
]
|
|
1262
|
+
elif enable_indexing:
|
|
1263
|
+
workflow_steps = [
|
|
1264
|
+
("🚀", "Initialize", "Setting up AI engine"),
|
|
1265
|
+
("📊", "Analyze", "Analyzing paper content"),
|
|
1266
|
+
("📥", "Download", "Processing document"),
|
|
1267
|
+
(
|
|
1268
|
+
"📋",
|
|
1269
|
+
"Plan",
|
|
1270
|
+
"Generating code plan",
|
|
1271
|
+
), # Phase 3: code planning orchestration
|
|
1272
|
+
(
|
|
1273
|
+
"🔍",
|
|
1274
|
+
"References",
|
|
1275
|
+
"Analyzing references",
|
|
1276
|
+
), # Phase 4: now conditional
|
|
1277
|
+
("📦", "Repos", "Downloading repositories"), # Phase 5: GitHub download
|
|
1278
|
+
("🗂️", "Index", "Building code index"), # Phase 6: code indexing
|
|
1279
|
+
("⚙️", "Implement", "Implementing code"), # Phase 7: code implementation
|
|
1280
|
+
]
|
|
1281
|
+
else:
|
|
1282
|
+
# Fast mode - skip References, Repos and Index steps
|
|
1283
|
+
workflow_steps = [
|
|
1284
|
+
("🚀", "Initialize", "Setting up AI engine"),
|
|
1285
|
+
("📊", "Analyze", "Analyzing paper content"),
|
|
1286
|
+
("📥", "Download", "Processing document"),
|
|
1287
|
+
(
|
|
1288
|
+
"📋",
|
|
1289
|
+
"Plan",
|
|
1290
|
+
"Generating code plan",
|
|
1291
|
+
), # Phase 3: code planning orchestration
|
|
1292
|
+
(
|
|
1293
|
+
"⚙️",
|
|
1294
|
+
"Implement",
|
|
1295
|
+
"Implementing code",
|
|
1296
|
+
), # Jump directly to implementation
|
|
1297
|
+
]
|
|
1298
|
+
|
|
1299
|
+
# Display step grid with fixed layout
|
|
1300
|
+
# Use a maximum of 8 columns for consistent sizing
|
|
1301
|
+
max_cols = 8
|
|
1302
|
+
cols = st.columns(max_cols)
|
|
1303
|
+
step_indicators = []
|
|
1304
|
+
|
|
1305
|
+
# Calculate column spacing for centering steps
|
|
1306
|
+
total_steps = len(workflow_steps)
|
|
1307
|
+
if total_steps <= max_cols:
|
|
1308
|
+
# Center the steps when fewer than max columns
|
|
1309
|
+
start_col = (max_cols - total_steps) // 2
|
|
1310
|
+
else:
|
|
1311
|
+
start_col = 0
|
|
1312
|
+
|
|
1313
|
+
for i, (icon, title, desc) in enumerate(workflow_steps):
|
|
1314
|
+
col_index = start_col + i if total_steps <= max_cols else i
|
|
1315
|
+
if col_index < max_cols:
|
|
1316
|
+
with cols[col_index]:
|
|
1317
|
+
step_placeholder = st.empty()
|
|
1318
|
+
step_indicators.append(step_placeholder)
|
|
1319
|
+
step_placeholder.markdown(
|
|
1320
|
+
f"""
|
|
1321
|
+
<div style="
|
|
1322
|
+
text-align: center;
|
|
1323
|
+
padding: 12px 8px;
|
|
1324
|
+
border-radius: 12px;
|
|
1325
|
+
background: rgba(255,255,255,0.05);
|
|
1326
|
+
margin: 5px 2px;
|
|
1327
|
+
border: 2px solid transparent;
|
|
1328
|
+
min-height: 90px;
|
|
1329
|
+
display: flex;
|
|
1330
|
+
flex-direction: column;
|
|
1331
|
+
justify-content: center;
|
|
1332
|
+
align-items: center;
|
|
1333
|
+
box-sizing: border-box;
|
|
1334
|
+
">
|
|
1335
|
+
<div style="font-size: 1.5rem; margin-bottom: 4px;">{icon}</div>
|
|
1336
|
+
<div style="font-size: 0.75rem; font-weight: 600; line-height: 1.2; margin-bottom: 2px;">{title}</div>
|
|
1337
|
+
<div style="font-size: 0.6rem; color: #888; line-height: 1.1; text-align: center;">{desc}</div>
|
|
1338
|
+
</div>
|
|
1339
|
+
""",
|
|
1340
|
+
unsafe_allow_html=True,
|
|
1341
|
+
)
|
|
1342
|
+
|
|
1343
|
+
# Create main progress bar
|
|
1344
|
+
st.markdown("#### Overall Progress")
|
|
1345
|
+
progress_bar = st.progress(0)
|
|
1346
|
+
|
|
1347
|
+
# Status text display
|
|
1348
|
+
status_text = st.empty()
|
|
1349
|
+
|
|
1350
|
+
# Display mode information
|
|
1351
|
+
if not enable_indexing:
|
|
1352
|
+
st.info(
|
|
1353
|
+
"⚡ Fast Mode: Reference analysis, GitHub repository download and codebase indexing are disabled for faster processing."
|
|
1354
|
+
)
|
|
1355
|
+
|
|
1356
|
+
return progress_bar, status_text, step_indicators, workflow_steps
|
|
1357
|
+
|
|
1358
|
+
|
|
1359
|
+
def update_step_indicator(
|
|
1360
|
+
step_indicators, workflow_steps, current_step: int, status: str = "active"
|
|
1361
|
+
):
|
|
1362
|
+
"""
|
|
1363
|
+
Update step indicator
|
|
1364
|
+
|
|
1365
|
+
Args:
|
|
1366
|
+
step_indicators: Step indicator list
|
|
1367
|
+
workflow_steps: Workflow steps definition
|
|
1368
|
+
current_step: Current step index
|
|
1369
|
+
status: Status ("active", "completed", "error")
|
|
1370
|
+
"""
|
|
1371
|
+
status_colors = {
|
|
1372
|
+
"pending": ("rgba(255,255,255,0.05)", "transparent", "#888"),
|
|
1373
|
+
"active": ("rgba(255,215,0,0.2)", "#ffd700", "#fff"),
|
|
1374
|
+
"completed": ("rgba(0,255,136,0.2)", "#00ff88", "#fff"),
|
|
1375
|
+
"error": ("rgba(255,99,99,0.2)", "#ff6363", "#fff"),
|
|
1376
|
+
}
|
|
1377
|
+
|
|
1378
|
+
for i, (icon, title, desc) in enumerate(workflow_steps):
|
|
1379
|
+
if i < current_step:
|
|
1380
|
+
bg_color, border_color, text_color = status_colors["completed"]
|
|
1381
|
+
display_icon = "✅"
|
|
1382
|
+
elif i == current_step:
|
|
1383
|
+
bg_color, border_color, text_color = status_colors[status]
|
|
1384
|
+
display_icon = icon
|
|
1385
|
+
else:
|
|
1386
|
+
bg_color, border_color, text_color = status_colors["pending"]
|
|
1387
|
+
display_icon = icon
|
|
1388
|
+
|
|
1389
|
+
step_indicators[i].markdown(
|
|
1390
|
+
f"""
|
|
1391
|
+
<div style="
|
|
1392
|
+
text-align: center;
|
|
1393
|
+
padding: 12px 8px;
|
|
1394
|
+
border-radius: 12px;
|
|
1395
|
+
background: {bg_color};
|
|
1396
|
+
margin: 5px 2px;
|
|
1397
|
+
border: 2px solid {border_color};
|
|
1398
|
+
color: {text_color};
|
|
1399
|
+
transition: all 0.3s ease;
|
|
1400
|
+
box-shadow: {f'0 0 15px {border_color}30' if i == current_step else 'none'};
|
|
1401
|
+
min-height: 90px;
|
|
1402
|
+
display: flex;
|
|
1403
|
+
flex-direction: column;
|
|
1404
|
+
justify-content: center;
|
|
1405
|
+
align-items: center;
|
|
1406
|
+
box-sizing: border-box;
|
|
1407
|
+
">
|
|
1408
|
+
<div style="font-size: 1.5rem; margin-bottom: 4px;">{display_icon}</div>
|
|
1409
|
+
<div style="font-size: 0.75rem; font-weight: 600; line-height: 1.2; margin-bottom: 2px;">{title}</div>
|
|
1410
|
+
<div style="font-size: 0.6rem; opacity: 0.8; line-height: 1.1; text-align: center;">{desc}</div>
|
|
1411
|
+
</div>
|
|
1412
|
+
""",
|
|
1413
|
+
unsafe_allow_html=True,
|
|
1414
|
+
)
|
|
1415
|
+
|
|
1416
|
+
|
|
1417
|
+
def footer_component():
|
|
1418
|
+
"""Footer component"""
|
|
1419
|
+
st.markdown("---")
|
|
1420
|
+
st.markdown(
|
|
1421
|
+
"""
|
|
1422
|
+
<div style="text-align: center; color: #666; padding: 2rem;">
|
|
1423
|
+
<p>🧬 <strong>DeepCode</strong> | Open-Source Code Agent | Data Intelligence Lab @ HKU |
|
|
1424
|
+
<a href="https://github.com/your-repo" target="_blank" style="color: var(--neon-blue);">GitHub</a></p>
|
|
1425
|
+
<p>⚡ Revolutionizing Research Reproducibility • Multi-Agent Architecture • Automated Code Generation</p>
|
|
1426
|
+
<p><small>💡 Join our growing community in building the future of automated research reproducibility</small></p>
|
|
1427
|
+
</div>
|
|
1428
|
+
""",
|
|
1429
|
+
unsafe_allow_html=True,
|
|
1430
|
+
)
|
|
1431
|
+
|
|
1432
|
+
|
|
1433
|
+
def format_file_size(size_bytes: int) -> str:
|
|
1434
|
+
"""
|
|
1435
|
+
Format file size
|
|
1436
|
+
|
|
1437
|
+
Args:
|
|
1438
|
+
size_bytes: Size in bytes
|
|
1439
|
+
|
|
1440
|
+
Returns:
|
|
1441
|
+
Formatted file size
|
|
1442
|
+
"""
|
|
1443
|
+
if size_bytes == 0:
|
|
1444
|
+
return "0B"
|
|
1445
|
+
size_names = ["B", "KB", "MB", "GB"]
|
|
1446
|
+
i = 0
|
|
1447
|
+
while size_bytes >= 1024 and i < len(size_names) - 1:
|
|
1448
|
+
size_bytes /= 1024.0
|
|
1449
|
+
i += 1
|
|
1450
|
+
return f"{size_bytes:.1f}{size_names[i]}"
|