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.
Files changed (44) hide show
  1. cli/__init__.py +18 -0
  2. cli/cli_app.py +296 -0
  3. cli/cli_interface.py +744 -0
  4. cli/cli_launcher.py +155 -0
  5. cli/main_cli.py +243 -0
  6. cli/workflows/__init__.py +11 -0
  7. cli/workflows/cli_workflow_adapter.py +336 -0
  8. deepcode.py +219 -0
  9. deepcode_hku-1.0.1.dist-info/METADATA +695 -0
  10. deepcode_hku-1.0.1.dist-info/RECORD +44 -0
  11. deepcode_hku-1.0.1.dist-info/WHEEL +5 -0
  12. deepcode_hku-1.0.1.dist-info/entry_points.txt +2 -0
  13. deepcode_hku-1.0.1.dist-info/licenses/LICENSE +21 -0
  14. deepcode_hku-1.0.1.dist-info/top_level.txt +6 -0
  15. tools/__init__.py +0 -0
  16. tools/code_implementation_server.py +1045 -0
  17. tools/code_indexer.py +1657 -0
  18. tools/code_reference_indexer.py +486 -0
  19. tools/command_executor.py +324 -0
  20. tools/git_command.py +356 -0
  21. tools/pdf_converter.py +640 -0
  22. tools/pdf_downloader.py +1370 -0
  23. tools/pdf_utils.py +52 -0
  24. ui/__init__.py +43 -0
  25. ui/app.py +13 -0
  26. ui/components.py +1450 -0
  27. ui/handlers.py +773 -0
  28. ui/layout.py +106 -0
  29. ui/streamlit_app.py +38 -0
  30. ui/styles.py +2116 -0
  31. utils/__init__.py +17 -0
  32. utils/cli_interface.py +459 -0
  33. utils/dialogue_logger.py +671 -0
  34. utils/file_processor.py +426 -0
  35. utils/simple_llm_logger.py +198 -0
  36. workflows/__init__.py +31 -0
  37. workflows/agent_orchestration_engine.py +1371 -0
  38. workflows/agents/__init__.py +13 -0
  39. workflows/agents/code_implementation_agent.py +1093 -0
  40. workflows/agents/memory_agent_concise.py +923 -0
  41. workflows/agents/memory_agent_concise_index.py +935 -0
  42. workflows/code_implementation_workflow.py +924 -0
  43. workflows/code_implementation_workflow_index.py +931 -0
  44. workflows/codebase_index_workflow.py +726 -0
cli/cli_interface.py ADDED
@@ -0,0 +1,744 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Enhanced CLI Interface Module for DeepCode
4
+ 增强版CLI界面模块 - 专为DeepCode设计
5
+ """
6
+
7
+ import os
8
+ import time
9
+ import platform
10
+ from typing import Optional
11
+
12
+
13
+ class Colors:
14
+ """ANSI color codes for terminal styling"""
15
+
16
+ HEADER = "\033[95m"
17
+ OKBLUE = "\033[94m"
18
+ OKCYAN = "\033[96m"
19
+ OKGREEN = "\033[92m"
20
+ WARNING = "\033[93m"
21
+ FAIL = "\033[91m"
22
+ ENDC = "\033[0m"
23
+ BOLD = "\033[1m"
24
+ UNDERLINE = "\033[4m"
25
+
26
+ # Gradient colors
27
+ PURPLE = "\033[35m"
28
+ MAGENTA = "\033[95m"
29
+ BLUE = "\033[34m"
30
+ CYAN = "\033[36m"
31
+ GREEN = "\033[32m"
32
+ YELLOW = "\033[33m"
33
+
34
+
35
+ class CLIInterface:
36
+ """Enhanced CLI interface with modern styling for DeepCode"""
37
+
38
+ def __init__(self):
39
+ self.uploaded_file = None
40
+ self.is_running = True
41
+ self.processing_history = []
42
+ self.enable_indexing = True # Default configuration
43
+
44
+ # Check tkinter availability for file dialogs
45
+ self.tkinter_available = True
46
+ try:
47
+ import tkinter as tk
48
+
49
+ # Test if tkinter can create a window
50
+ test_root = tk.Tk()
51
+ test_root.withdraw()
52
+ test_root.destroy()
53
+ except Exception:
54
+ self.tkinter_available = False
55
+
56
+ def clear_screen(self):
57
+ """Clear terminal screen"""
58
+ os.system("cls" if os.name == "nt" else "clear")
59
+
60
+ def print_logo(self):
61
+ """Print enhanced ASCII logo for DeepCode CLI"""
62
+ logo = f"""
63
+ {Colors.CYAN}╔═══════════════════════════════════════════════════════════════════════════════╗
64
+ ║ ║
65
+ ║ {Colors.BOLD}{Colors.MAGENTA}██████╗ ███████╗███████╗██████╗ ██████╗ ██████╗ ██████╗ ███████╗{Colors.CYAN} ║
66
+ ║ {Colors.BOLD}{Colors.PURPLE}██╔══██╗██╔════╝██╔════╝██╔══██╗██╔════╝██╔═══██╗██╔══██╗██╔════╝{Colors.CYAN} ║
67
+ ║ {Colors.BOLD}{Colors.BLUE}██║ ██║█████╗ █████╗ ██████╔╝██║ ██║ ██║██║ ██║█████╗ {Colors.CYAN} ║
68
+ ║ {Colors.BOLD}{Colors.OKBLUE}██║ ██║██╔══╝ ██╔══╝ ██╔═══╝ ██║ ██║ ██║██║ ██║██╔══╝ {Colors.CYAN} ║
69
+ ║ {Colors.BOLD}{Colors.OKCYAN}██████╔╝███████╗███████╗██║ ╚██████╗╚██████╔╝██████╔╝███████╗{Colors.CYAN} ║
70
+ ║ {Colors.BOLD}{Colors.GREEN}╚═════╝ ╚══════╝╚══════╝╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝{Colors.CYAN} ║
71
+ ║ ║
72
+ ║ {Colors.BOLD}{Colors.GREEN}🧬 OPEN-SOURCE CODE AGENT • DATA INTELLIGENCE LAB @ HKU 🚀 {Colors.CYAN}║
73
+ ║ {Colors.BOLD}{Colors.GREEN}⚡ REVOLUTIONIZING RESEARCH REPRODUCIBILITY ⚡ {Colors.CYAN}║
74
+ ║ ║
75
+ ╚═══════════════════════════════════════════════════════════════════════════════╝{Colors.ENDC}
76
+ """
77
+ print(logo)
78
+
79
+ def print_welcome_banner(self):
80
+ """Print enhanced welcome banner"""
81
+ banner = f"""
82
+ {Colors.BOLD}{Colors.CYAN}╔═══════════════════════════════════════════════════════════════════════════════╗
83
+ ║ WELCOME TO DEEPCODE CLI ║
84
+ ╠═══════════════════════════════════════════════════════════════════════════════╣
85
+ ║ {Colors.YELLOW}Open-Source Code Agent | Data Intelligence Lab @ HKU | MIT License {Colors.CYAN}║
86
+ ║ {Colors.GREEN}Status: Ready | Engine: Multi-Agent Architecture Initialized {Colors.CYAN}║
87
+ ║ {Colors.PURPLE}Mission: Revolutionizing Research Reproducibility {Colors.CYAN}║
88
+ ║ ║
89
+ ║ {Colors.BOLD}{Colors.OKCYAN}💎 CORE CAPABILITIES:{Colors.ENDC} {Colors.CYAN}║
90
+ ║ {Colors.BOLD}{Colors.OKCYAN}▶ Automated Paper-to-Code Reproduction {Colors.CYAN}║
91
+ ║ {Colors.BOLD}{Colors.OKCYAN}▶ Collaborative Multi-Agent Architecture {Colors.CYAN}║
92
+ ║ {Colors.BOLD}{Colors.OKCYAN}▶ Intelligent Code Implementation & Validation {Colors.CYAN}║
93
+ ║ {Colors.BOLD}{Colors.OKCYAN}▶ Future Vision: One Sentence → Complete Codebase {Colors.CYAN}║
94
+ ╚═══════════════════════════════════════════════════════════════════════════════╝{Colors.ENDC}
95
+ """
96
+ print(banner)
97
+
98
+ def print_separator(self, char="═", length=79, color=Colors.CYAN):
99
+ """Print a styled separator line"""
100
+ print(f"{color}{char * length}{Colors.ENDC}")
101
+
102
+ def print_status(self, message: str, status_type: str = "info"):
103
+ """Print status message with appropriate styling"""
104
+ status_styles = {
105
+ "success": f"{Colors.OKGREEN}✅",
106
+ "error": f"{Colors.FAIL}❌",
107
+ "warning": f"{Colors.WARNING}⚠️ ",
108
+ "info": f"{Colors.OKBLUE}ℹ️ ",
109
+ "processing": f"{Colors.YELLOW}⏳",
110
+ "upload": f"{Colors.PURPLE}📁",
111
+ "download": f"{Colors.CYAN}📥",
112
+ "analysis": f"{Colors.MAGENTA}🔍",
113
+ "implementation": f"{Colors.GREEN}⚙️ ",
114
+ "complete": f"{Colors.OKGREEN}🎉",
115
+ }
116
+
117
+ icon = status_styles.get(status_type, status_styles["info"])
118
+ timestamp = time.strftime("%H:%M:%S")
119
+ print(
120
+ f"[{Colors.BOLD}{timestamp}{Colors.ENDC}] {icon} {Colors.BOLD}{message}{Colors.ENDC}"
121
+ )
122
+
123
+ def create_menu(self):
124
+ """Create enhanced interactive menu"""
125
+ # Display current configuration
126
+ pipeline_mode = "🧠 COMPREHENSIVE" if self.enable_indexing else "⚡ OPTIMIZED"
127
+ index_status = "✅ Enabled" if self.enable_indexing else "🔶 Disabled"
128
+
129
+ menu = f"""
130
+ {Colors.BOLD}{Colors.CYAN}╔═══════════════════════════════════════════════════════════════════════════════╗
131
+ ║ MAIN MENU ║
132
+ ╠═══════════════════════════════════════════════════════════════════════════════╣
133
+ ║ {Colors.OKGREEN}🌐 [U] Process URL {Colors.CYAN}│ {Colors.PURPLE}📁 [F] Upload File {Colors.CYAN}│ {Colors.MAGENTA}💬 [T] Chat Input{Colors.CYAN} ║
134
+ ║ {Colors.OKCYAN}⚙️ [C] Configure {Colors.CYAN}│ {Colors.YELLOW}📊 [H] History {Colors.CYAN}│ {Colors.FAIL}❌ [Q] Quit{Colors.CYAN} ║
135
+ ║ ║
136
+ ║ {Colors.BOLD}🤖 Current Pipeline Mode: {pipeline_mode}{Colors.CYAN} ║
137
+ ║ {Colors.BOLD}🗂️ Codebase Indexing: {index_status}{Colors.CYAN} ║
138
+ ║ ║
139
+ ║ {Colors.YELLOW}📝 URL Processing:{Colors.CYAN} ║
140
+ ║ {Colors.YELLOW} ▶ Enter research paper URL (arXiv, IEEE, ACM, etc.) {Colors.CYAN}║
141
+ ║ {Colors.YELLOW} ▶ Supports direct PDF links and academic paper pages {Colors.CYAN}║
142
+ ║ ║
143
+ ║ {Colors.PURPLE}📁 File Processing:{Colors.CYAN} ║
144
+ ║ {Colors.PURPLE} ▶ Upload PDF, DOCX, PPTX, HTML, or TXT files {Colors.CYAN}║
145
+ ║ {Colors.PURPLE} ▶ Intelligent file format detection and processing {Colors.CYAN}║
146
+ ║ ║
147
+ ║ {Colors.MAGENTA}💬 Chat Input:{Colors.CYAN} ║
148
+ ║ {Colors.MAGENTA} ▶ Describe your coding requirements in natural language {Colors.CYAN}║
149
+ ║ {Colors.MAGENTA} ▶ AI generates implementation plan and code automatically {Colors.CYAN}║
150
+ ║ ║
151
+ ║ {Colors.OKCYAN}🔄 Processing Pipeline:{Colors.CYAN} ║
152
+ ║ {Colors.OKCYAN} ▶ Intelligent agent orchestration → Code synthesis {Colors.CYAN}║
153
+ ║ {Colors.OKCYAN} ▶ Multi-agent coordination with progress tracking {Colors.CYAN}║
154
+ ╚═══════════════════════════════════════════════════════════════════════════════╝{Colors.ENDC}
155
+ """
156
+ print(menu)
157
+
158
+ def get_user_input(self):
159
+ """Get user input with styled prompt"""
160
+ print(f"\n{Colors.BOLD}{Colors.OKCYAN}➤ Your choice: {Colors.ENDC}", end="")
161
+ return input().strip().lower()
162
+
163
+ def upload_file_gui(self) -> Optional[str]:
164
+ """Enhanced file upload interface with better error handling"""
165
+ if not self.tkinter_available:
166
+ self.print_status(
167
+ "GUI file dialog not available - using manual input", "warning"
168
+ )
169
+ return self._get_manual_file_path()
170
+
171
+ def select_file():
172
+ try:
173
+ import tkinter as tk
174
+ from tkinter import filedialog
175
+
176
+ root = tk.Tk()
177
+ root.withdraw()
178
+ root.attributes("-topmost", True)
179
+
180
+ file_types = [
181
+ ("Research Papers", "*.pdf;*.docx;*.doc"),
182
+ ("PDF Files", "*.pdf"),
183
+ ("Word Documents", "*.docx;*.doc"),
184
+ ("PowerPoint Files", "*.pptx;*.ppt"),
185
+ ("HTML Files", "*.html;*.htm"),
186
+ ("Text Files", "*.txt;*.md"),
187
+ ("All Files", "*.*"),
188
+ ]
189
+
190
+ if platform.system() == "Darwin":
191
+ file_types = [
192
+ ("Research Papers", ".pdf .docx .doc"),
193
+ ("PDF Files", ".pdf"),
194
+ ("Word Documents", ".docx .doc"),
195
+ ("PowerPoint Files", ".pptx .ppt"),
196
+ ("HTML Files", ".html .htm"),
197
+ ("Text Files", ".txt .md"),
198
+ ("All Files", ".*"),
199
+ ]
200
+
201
+ file_path = filedialog.askopenfilename(
202
+ title="Select Research File - DeepCode CLI",
203
+ filetypes=file_types,
204
+ initialdir=os.getcwd(),
205
+ )
206
+
207
+ root.destroy()
208
+ return file_path
209
+
210
+ except Exception as e:
211
+ self.print_status(f"File dialog error: {str(e)}", "error")
212
+ return self._get_manual_file_path()
213
+
214
+ self.print_status("Opening file browser dialog...", "upload")
215
+ file_path = select_file()
216
+
217
+ if file_path:
218
+ self.print_status(
219
+ f"File selected: {os.path.basename(file_path)}", "success"
220
+ )
221
+ return file_path
222
+ else:
223
+ self.print_status("No file selected", "warning")
224
+ return None
225
+
226
+ def _get_manual_file_path(self) -> Optional[str]:
227
+ """Get file path through manual input with validation"""
228
+ self.print_separator("─", 79, Colors.YELLOW)
229
+ print(f"{Colors.BOLD}{Colors.YELLOW}📁 Manual File Path Input{Colors.ENDC}")
230
+ print(
231
+ f"{Colors.CYAN}Please enter the full path to your research paper file:{Colors.ENDC}"
232
+ )
233
+ print(
234
+ f"{Colors.CYAN}Supported formats: PDF, DOCX, PPTX, HTML, TXT, MD{Colors.ENDC}"
235
+ )
236
+ self.print_separator("─", 79, Colors.YELLOW)
237
+
238
+ while True:
239
+ print(f"\n{Colors.BOLD}{Colors.OKCYAN}📂 File path: {Colors.ENDC}", end="")
240
+ file_path = input().strip()
241
+
242
+ if not file_path:
243
+ self.print_status(
244
+ "Empty path entered. Please try again or press Ctrl+C to cancel.",
245
+ "warning",
246
+ )
247
+ continue
248
+
249
+ file_path = os.path.expanduser(file_path)
250
+ file_path = os.path.abspath(file_path)
251
+
252
+ if not os.path.exists(file_path):
253
+ self.print_status(f"File not found: {file_path}", "error")
254
+ retry = (
255
+ input(f"{Colors.YELLOW}Try again? (y/n): {Colors.ENDC}")
256
+ .strip()
257
+ .lower()
258
+ )
259
+ if retry != "y":
260
+ return None
261
+ continue
262
+
263
+ if not os.path.isfile(file_path):
264
+ self.print_status(f"Path is not a file: {file_path}", "error")
265
+ continue
266
+
267
+ supported_extensions = {
268
+ ".pdf",
269
+ ".docx",
270
+ ".doc",
271
+ ".pptx",
272
+ ".ppt",
273
+ ".html",
274
+ ".htm",
275
+ ".txt",
276
+ ".md",
277
+ }
278
+ file_ext = os.path.splitext(file_path)[1].lower()
279
+
280
+ if file_ext not in supported_extensions:
281
+ self.print_status(f"Unsupported file format: {file_ext}", "warning")
282
+ proceed = (
283
+ input(f"{Colors.YELLOW}Process anyway? (y/n): {Colors.ENDC}")
284
+ .strip()
285
+ .lower()
286
+ )
287
+ if proceed != "y":
288
+ continue
289
+
290
+ self.print_status(
291
+ f"File validated: {os.path.basename(file_path)}", "success"
292
+ )
293
+ return file_path
294
+
295
+ def get_url_input(self) -> str:
296
+ """Enhanced URL input with validation"""
297
+ self.print_separator("─", 79, Colors.GREEN)
298
+ print(f"{Colors.BOLD}{Colors.GREEN}🌐 URL Input Interface{Colors.ENDC}")
299
+ print(
300
+ f"{Colors.CYAN}Enter a research paper URL from supported platforms:{Colors.ENDC}"
301
+ )
302
+ print(
303
+ f"{Colors.CYAN}• arXiv (arxiv.org) • IEEE Xplore (ieeexplore.ieee.org){Colors.ENDC}"
304
+ )
305
+ print(
306
+ f"{Colors.CYAN}• ACM Digital Library • SpringerLink • Nature • Science{Colors.ENDC}"
307
+ )
308
+ print(
309
+ f"{Colors.CYAN}• Direct PDF links • Academic publisher websites{Colors.ENDC}"
310
+ )
311
+ self.print_separator("─", 79, Colors.GREEN)
312
+
313
+ while True:
314
+ print(f"\n{Colors.BOLD}{Colors.OKCYAN}🔗 URL: {Colors.ENDC}", end="")
315
+ url = input().strip()
316
+
317
+ if not url:
318
+ self.print_status(
319
+ "Empty URL entered. Please try again or press Ctrl+C to cancel.",
320
+ "warning",
321
+ )
322
+ continue
323
+
324
+ if not url.startswith(("http://", "https://")):
325
+ self.print_status("URL must start with http:// or https://", "error")
326
+ retry = (
327
+ input(f"{Colors.YELLOW}Try again? (y/n): {Colors.ENDC}")
328
+ .strip()
329
+ .lower()
330
+ )
331
+ if retry != "y":
332
+ return ""
333
+ continue
334
+
335
+ academic_domains = [
336
+ "arxiv.org",
337
+ "ieeexplore.ieee.org",
338
+ "dl.acm.org",
339
+ "link.springer.com",
340
+ "nature.com",
341
+ "science.org",
342
+ "scholar.google.com",
343
+ "researchgate.net",
344
+ "semanticscholar.org",
345
+ ]
346
+
347
+ is_academic = any(domain in url.lower() for domain in academic_domains)
348
+ if not is_academic and not url.lower().endswith(".pdf"):
349
+ self.print_status(
350
+ "URL doesn't appear to be from a known academic platform", "warning"
351
+ )
352
+ proceed = (
353
+ input(f"{Colors.YELLOW}Process anyway? (y/n): {Colors.ENDC}")
354
+ .strip()
355
+ .lower()
356
+ )
357
+ if proceed != "y":
358
+ continue
359
+
360
+ self.print_status(f"URL validated: {url}", "success")
361
+ return url
362
+
363
+ def get_chat_input(self) -> str:
364
+ """Enhanced chat input interface for coding requirements"""
365
+ self.print_separator("─", 79, Colors.PURPLE)
366
+ print(f"{Colors.BOLD}{Colors.PURPLE}💬 Chat Input Interface{Colors.ENDC}")
367
+ print(
368
+ f"{Colors.CYAN}Describe your coding requirements in natural language.{Colors.ENDC}"
369
+ )
370
+ print(
371
+ f"{Colors.CYAN}Our AI will analyze your needs and generate a comprehensive implementation plan.{Colors.ENDC}"
372
+ )
373
+ self.print_separator("─", 79, Colors.PURPLE)
374
+
375
+ # Display examples to help users
376
+ print(f"\n{Colors.BOLD}{Colors.YELLOW}💡 Examples:{Colors.ENDC}")
377
+ print(f"{Colors.CYAN}Academic Research:{Colors.ENDC}")
378
+ print(
379
+ " • 'I need to implement a reinforcement learning algorithm for robotic control'"
380
+ )
381
+ print(
382
+ " • 'Create a neural network for image classification with attention mechanisms'"
383
+ )
384
+ print(f"{Colors.CYAN}Engineering Projects:{Colors.ENDC}")
385
+ print(
386
+ " • 'Develop a web application for project management with user authentication'"
387
+ )
388
+ print(" • 'Create a data visualization dashboard for sales analytics'")
389
+ print(f"{Colors.CYAN}Mixed Projects:{Colors.ENDC}")
390
+ print(
391
+ " • 'Implement a machine learning model with a web interface for real-time predictions'"
392
+ )
393
+
394
+ self.print_separator("─", 79, Colors.PURPLE)
395
+
396
+ print(
397
+ f"\n{Colors.BOLD}{Colors.OKCYAN}✏️ Enter your coding requirements below:{Colors.ENDC}"
398
+ )
399
+ print(
400
+ f"{Colors.YELLOW}(Type your description, press Enter twice when finished, or Ctrl+C to cancel){Colors.ENDC}"
401
+ )
402
+
403
+ lines = []
404
+ empty_line_count = 0
405
+
406
+ while True:
407
+ try:
408
+ if len(lines) == 0:
409
+ print(f"{Colors.BOLD}> {Colors.ENDC}", end="")
410
+ else:
411
+ print(f"{Colors.BOLD} {Colors.ENDC}", end="")
412
+
413
+ line = input()
414
+
415
+ if line.strip() == "":
416
+ empty_line_count += 1
417
+ if empty_line_count >= 2:
418
+ # Two consecutive empty lines means user finished input
419
+ break
420
+ lines.append("") # Keep empty line for formatting
421
+ else:
422
+ empty_line_count = 0
423
+ lines.append(line)
424
+
425
+ except KeyboardInterrupt:
426
+ print(f"\n{Colors.WARNING}Input cancelled by user{Colors.ENDC}")
427
+ return ""
428
+
429
+ # Join all lines and clean up
430
+ user_input = "\n".join(lines).strip()
431
+
432
+ if not user_input:
433
+ self.print_status("No input provided", "warning")
434
+ return ""
435
+
436
+ if len(user_input) < 20:
437
+ self.print_status(
438
+ "Input too short. Please provide more detailed requirements (at least 20 characters)",
439
+ "warning",
440
+ )
441
+ retry = (
442
+ input(f"{Colors.YELLOW}Try again? (y/n): {Colors.ENDC}").strip().lower()
443
+ )
444
+ if retry == "y":
445
+ return self.get_chat_input() # Recursive call for retry
446
+ return ""
447
+
448
+ # Display input summary
449
+ word_count = len(user_input.split())
450
+ char_count = len(user_input)
451
+
452
+ print(f"\n{Colors.BOLD}{Colors.GREEN}📋 Input Summary:{Colors.ENDC}")
453
+ print(f" • {Colors.CYAN}Word count: {word_count}{Colors.ENDC}")
454
+ print(f" • {Colors.CYAN}Character count: {char_count}{Colors.ENDC}")
455
+
456
+ # Show preview
457
+ preview = user_input[:200] + "..." if len(user_input) > 200 else user_input
458
+ print(f"\n{Colors.BOLD}{Colors.CYAN}📄 Preview:{Colors.ENDC}")
459
+ print(f"{Colors.YELLOW}{preview}{Colors.ENDC}")
460
+
461
+ # Confirm with user
462
+ confirm = (
463
+ input(
464
+ f"\n{Colors.BOLD}{Colors.OKCYAN}Proceed with this input? (y/n): {Colors.ENDC}"
465
+ )
466
+ .strip()
467
+ .lower()
468
+ )
469
+ if confirm != "y":
470
+ retry = (
471
+ input(f"{Colors.YELLOW}Edit input? (y/n): {Colors.ENDC}")
472
+ .strip()
473
+ .lower()
474
+ )
475
+ if retry == "y":
476
+ return self.get_chat_input() # Recursive call for retry
477
+ return ""
478
+
479
+ self.print_status(
480
+ f"Chat input captured: {word_count} words, {char_count} characters",
481
+ "success",
482
+ )
483
+ return user_input
484
+
485
+ def show_progress_bar(self, message: str, duration: float = 2.0):
486
+ """Show animated progress bar"""
487
+ print(f"\n{Colors.BOLD}{Colors.CYAN}{message}{Colors.ENDC}")
488
+
489
+ bar_length = 50
490
+ for i in range(bar_length + 1):
491
+ percent = (i / bar_length) * 100
492
+ filled = "█" * i
493
+ empty = "░" * (bar_length - i)
494
+
495
+ print(
496
+ f"\r{Colors.OKGREEN}[{filled}{empty}] {percent:3.0f}%{Colors.ENDC}",
497
+ end="",
498
+ flush=True,
499
+ )
500
+ time.sleep(duration / bar_length)
501
+
502
+ print(f"\n{Colors.OKGREEN}✓ {message} completed{Colors.ENDC}")
503
+
504
+ def show_spinner(self, message: str, duration: float = 1.0):
505
+ """Show spinner animation"""
506
+ spinner_chars = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
507
+ end_time = time.time() + duration
508
+
509
+ print(
510
+ f"{Colors.BOLD}{Colors.CYAN}{message}... {Colors.ENDC}", end="", flush=True
511
+ )
512
+
513
+ i = 0
514
+ while time.time() < end_time:
515
+ print(
516
+ f"\r{Colors.BOLD}{Colors.CYAN}{message}... {Colors.YELLOW}{spinner_chars[i % len(spinner_chars)]}{Colors.ENDC}",
517
+ end="",
518
+ flush=True,
519
+ )
520
+ time.sleep(0.1)
521
+ i += 1
522
+
523
+ print(
524
+ f"\r{Colors.BOLD}{Colors.CYAN}{message}... {Colors.OKGREEN}✓{Colors.ENDC}"
525
+ )
526
+
527
+ def display_processing_stages(
528
+ self,
529
+ current_stage: int = 0,
530
+ enable_indexing: bool = True,
531
+ chat_mode: bool = False,
532
+ ):
533
+ """Display processing pipeline stages with current progress"""
534
+ if chat_mode:
535
+ # Chat mode - simplified workflow for user requirements
536
+ stages = [
537
+ ("🚀", "Initialize", "Setting up chat engine"),
538
+ ("💬", "Planning", "Analyzing requirements"),
539
+ ("🏗️", "Setup", "Creating workspace"),
540
+ ("📝", "Save Plan", "Saving implementation plan"),
541
+ ("⚙️", "Implement", "Generating code"),
542
+ ]
543
+ pipeline_mode = "CHAT PLANNING"
544
+ elif enable_indexing:
545
+ # Full pipeline with all stages
546
+ stages = [
547
+ ("🚀", "Initialize", "Setting up AI engine"),
548
+ ("📊", "Analyze", "Analyzing research content"),
549
+ ("📥", "Download", "Processing document"),
550
+ ("📋", "Plan", "Generating code architecture"),
551
+ ("🔍", "References", "Analyzing references"),
552
+ ("📦", "Repos", "Downloading repositories"),
553
+ ("🗂️", "Index", "Building code index"),
554
+ ("⚙️", "Implement", "Implementing code"),
555
+ ]
556
+ pipeline_mode = "COMPREHENSIVE"
557
+ else:
558
+ # Fast mode - skip indexing related stages
559
+ stages = [
560
+ ("🚀", "Initialize", "Setting up AI engine"),
561
+ ("📊", "Analyze", "Analyzing research content"),
562
+ ("📥", "Download", "Processing document"),
563
+ ("📋", "Plan", "Generating code architecture"),
564
+ ("⚙️", "Implement", "Implementing code"),
565
+ ]
566
+ pipeline_mode = "OPTIMIZED"
567
+
568
+ print(
569
+ f"\n{Colors.BOLD}{Colors.CYAN}📋 {pipeline_mode} PIPELINE STATUS{Colors.ENDC}"
570
+ )
571
+ self.print_separator("─", 79, Colors.CYAN)
572
+
573
+ for i, (icon, name, desc) in enumerate(stages):
574
+ if i < current_stage:
575
+ status = f"{Colors.OKGREEN}✓ COMPLETED{Colors.ENDC}"
576
+ elif i == current_stage:
577
+ status = f"{Colors.YELLOW}⏳ IN PROGRESS{Colors.ENDC}"
578
+ else:
579
+ status = f"{Colors.CYAN}⏸️ PENDING{Colors.ENDC}"
580
+
581
+ print(
582
+ f"{icon} {Colors.BOLD}{name:<12}{Colors.ENDC} │ {desc:<25} │ {status}"
583
+ )
584
+
585
+ self.print_separator("─", 79, Colors.CYAN)
586
+
587
+ def print_results_header(self):
588
+ """Print results section header"""
589
+ header = f"""
590
+ {Colors.BOLD}{Colors.OKGREEN}╔═══════════════════════════════════════════════════════════════════════════════╗
591
+ ║ PROCESSING RESULTS ║
592
+ ╚═══════════════════════════════════════════════════════════════════════════════╝{Colors.ENDC}
593
+ """
594
+ print(header)
595
+
596
+ def print_error_box(self, title: str, error_msg: str):
597
+ """Print formatted error box"""
598
+ print(
599
+ f"\n{Colors.FAIL}╔══════════════════════════════════════════════════════════════╗"
600
+ )
601
+ print(f"║ {Colors.BOLD}ERROR: {title:<50}{Colors.FAIL} ║")
602
+ print("╠══════════════════════════════════════════════════════════════╣")
603
+
604
+ words = error_msg.split()
605
+ lines = []
606
+ current_line = ""
607
+
608
+ for word in words:
609
+ if len(current_line + word) <= 54:
610
+ current_line += word + " "
611
+ else:
612
+ lines.append(current_line.strip())
613
+ current_line = word + " "
614
+ if current_line:
615
+ lines.append(current_line.strip())
616
+
617
+ for line in lines:
618
+ print(f"║ {line:<56} ║")
619
+
620
+ print(
621
+ f"╚══════════════════════════════════════════════════════════════╝{Colors.ENDC}"
622
+ )
623
+
624
+ def cleanup_cache(self):
625
+ """清理Python缓存文件 / Clean up Python cache files"""
626
+ try:
627
+ self.print_status("Cleaning up cache files...", "info")
628
+ # 清理__pycache__目录
629
+ os.system('find . -type d -name "__pycache__" -exec rm -r {} + 2>/dev/null')
630
+ # 清理.pyc文件
631
+ os.system('find . -name "*.pyc" -delete 2>/dev/null')
632
+ self.print_status("Cache cleanup completed", "success")
633
+ except Exception as e:
634
+ self.print_status(f"Cache cleanup failed: {e}", "warning")
635
+
636
+ def print_goodbye(self):
637
+ """Print goodbye message"""
638
+ # 清理缓存文件
639
+ self.cleanup_cache()
640
+
641
+ goodbye = f"""
642
+ {Colors.BOLD}{Colors.CYAN}╔═══════════════════════════════════════════════════════════════════════════════╗
643
+ ║ GOODBYE ║
644
+ ╠═══════════════════════════════════════════════════════════════════════════════╣
645
+ ║ {Colors.OKGREEN}🎉 Thank you for using DeepCode CLI! {Colors.CYAN}║
646
+ ║ ║
647
+ ║ {Colors.YELLOW}🧬 Join our community in revolutionizing research reproducibility {Colors.CYAN}║
648
+ ║ {Colors.PURPLE}⚡ Together, we're building the future of automated code generation {Colors.CYAN}║
649
+ ║ ║
650
+ ║ {Colors.OKCYAN}💡 Questions? Contribute to our open-source mission at GitHub {Colors.CYAN}║
651
+ ║ {Colors.GREEN}🧹 Cache files cleaned up for optimal performance {Colors.CYAN}║
652
+ ║ ║
653
+ ╚═══════════════════════════════════════════════════════════════════════════════╝{Colors.ENDC}
654
+ """
655
+ print(goodbye)
656
+
657
+ def ask_continue(self) -> bool:
658
+ """Ask if user wants to continue with another paper"""
659
+ self.print_separator("─", 79, Colors.YELLOW)
660
+ print(f"\n{Colors.BOLD}{Colors.YELLOW}🔄 Process another paper?{Colors.ENDC}")
661
+ choice = input(f"{Colors.OKCYAN}Continue? (y/n): {Colors.ENDC}").strip().lower()
662
+ return choice in ["y", "yes", "1", "true"]
663
+
664
+ def add_to_history(self, input_source: str, result: dict):
665
+ """Add processing result to history"""
666
+ entry = {
667
+ "timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
668
+ "input_source": input_source,
669
+ "status": result.get("status", "unknown"),
670
+ "result": result,
671
+ }
672
+ self.processing_history.append(entry)
673
+
674
+ def show_history(self):
675
+ """Display processing history"""
676
+ if not self.processing_history:
677
+ self.print_status("No processing history available", "info")
678
+ return
679
+
680
+ print(f"\n{Colors.BOLD}{Colors.CYAN}📚 PROCESSING HISTORY{Colors.ENDC}")
681
+ self.print_separator("─", 79, Colors.CYAN)
682
+
683
+ for i, entry in enumerate(self.processing_history, 1):
684
+ status_icon = "✅" if entry["status"] == "success" else "❌"
685
+ source = entry["input_source"]
686
+ if len(source) > 50:
687
+ source = source[:47] + "..."
688
+
689
+ print(f"{i}. {status_icon} {entry['timestamp']} | {source}")
690
+
691
+ self.print_separator("─", 79, Colors.CYAN)
692
+
693
+ def show_configuration_menu(self):
694
+ """Show configuration options menu"""
695
+ self.clear_screen()
696
+ print(f"""
697
+ {Colors.BOLD}{Colors.CYAN}╔═══════════════════════════════════════════════════════════════════════════════╗
698
+ ║ CONFIGURATION MENU ║
699
+ ╠═══════════════════════════════════════════════════════════════════════════════╣
700
+ ║ ║
701
+ ║ {Colors.BOLD}🤖 Agent Orchestration Engine Configuration{Colors.CYAN} ║
702
+ ║ ║
703
+ ║ {Colors.OKCYAN}[1] Pipeline Mode:{Colors.CYAN} ║
704
+ ║ {Colors.BOLD}🧠 Comprehensive Mode{Colors.CYAN} - Full intelligence analysis (Default) ║
705
+ ║ ✓ Research Analysis + Resource Processing ║
706
+ ║ ✓ Reference Intelligence Discovery ║
707
+ ║ ✓ Automated Repository Acquisition ║
708
+ ║ ✓ Codebase Intelligence Orchestration ║
709
+ ║ ✓ Intelligent Code Implementation Synthesis ║
710
+ ║ ║
711
+ ║ {Colors.BOLD}⚡ Optimized Mode{Colors.CYAN} - Fast processing (Skip indexing) ║
712
+ ║ ✓ Research Analysis + Resource Processing ║
713
+ ║ ✓ Code Architecture Synthesis ║
714
+ ║ ✓ Intelligent Code Implementation Synthesis ║
715
+ ║ ✗ Reference Intelligence Discovery (Skipped) ║
716
+ ║ ✗ Repository Acquisition (Skipped) ║
717
+ ║ ✗ Codebase Intelligence Orchestration (Skipped) ║
718
+ ║ ║
719
+ ║ {Colors.YELLOW}Current Setting:{Colors.CYAN} {'🧠 Comprehensive Mode' if self.enable_indexing else '⚡ Optimized Mode'} ║
720
+ ║ ║
721
+ ║ {Colors.OKGREEN}[T] Toggle Pipeline Mode {Colors.CYAN}│ {Colors.FAIL}[B] Back to Main Menu{Colors.CYAN} ║
722
+ ╚═══════════════════════════════════════════════════════════════════════════════╝{Colors.ENDC}
723
+ """)
724
+
725
+ while True:
726
+ print(
727
+ f"\n{Colors.BOLD}{Colors.OKCYAN}➤ Configuration choice: {Colors.ENDC}",
728
+ end="",
729
+ )
730
+ choice = input().strip().lower()
731
+
732
+ if choice in ["t", "toggle"]:
733
+ self.enable_indexing = not self.enable_indexing
734
+ mode = "🧠 Comprehensive" if self.enable_indexing else "⚡ Optimized"
735
+ self.print_status(f"Pipeline mode switched to: {mode}", "success")
736
+ time.sleep(1)
737
+ self.show_configuration_menu()
738
+ return
739
+
740
+ elif choice in ["b", "back"]:
741
+ return
742
+
743
+ else:
744
+ self.print_status("Invalid choice. Please enter 'T' or 'B'.", "warning")