realtimex-deeptutor 0.5.0.post1__py3-none-any.whl → 0.5.0.post3__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 (145) hide show
  1. {realtimex_deeptutor-0.5.0.post1.dist-info → realtimex_deeptutor-0.5.0.post3.dist-info}/METADATA +24 -17
  2. {realtimex_deeptutor-0.5.0.post1.dist-info → realtimex_deeptutor-0.5.0.post3.dist-info}/RECORD +143 -123
  3. {realtimex_deeptutor-0.5.0.post1.dist-info → realtimex_deeptutor-0.5.0.post3.dist-info}/WHEEL +1 -1
  4. realtimex_deeptutor-0.5.0.post3.dist-info/entry_points.txt +4 -0
  5. {realtimex_deeptutor-0.5.0.post1.dist-info → realtimex_deeptutor-0.5.0.post3.dist-info}/top_level.txt +1 -0
  6. scripts/__init__.py +1 -0
  7. scripts/audit_prompts.py +179 -0
  8. scripts/check_install.py +460 -0
  9. scripts/generate_roster.py +327 -0
  10. scripts/install_all.py +653 -0
  11. scripts/migrate_kb.py +655 -0
  12. scripts/start.py +807 -0
  13. scripts/start_web.py +632 -0
  14. scripts/sync_prompts_from_en.py +147 -0
  15. src/__init__.py +2 -2
  16. src/agents/ideagen/material_organizer_agent.py +2 -0
  17. src/agents/solve/__init__.py +6 -0
  18. src/agents/solve/main_solver.py +9 -0
  19. src/agents/solve/prompts/zh/analysis_loop/investigate_agent.yaml +9 -7
  20. src/agents/solve/session_manager.py +345 -0
  21. src/api/main.py +14 -0
  22. src/api/routers/chat.py +3 -3
  23. src/api/routers/co_writer.py +12 -7
  24. src/api/routers/config.py +1 -0
  25. src/api/routers/guide.py +3 -1
  26. src/api/routers/ideagen.py +7 -0
  27. src/api/routers/knowledge.py +64 -12
  28. src/api/routers/question.py +2 -0
  29. src/api/routers/realtimex.py +137 -0
  30. src/api/routers/research.py +9 -0
  31. src/api/routers/solve.py +120 -2
  32. src/cli/__init__.py +13 -0
  33. src/cli/start.py +209 -0
  34. src/config/constants.py +11 -9
  35. src/knowledge/add_documents.py +453 -213
  36. src/knowledge/extract_numbered_items.py +9 -10
  37. src/knowledge/initializer.py +102 -101
  38. src/knowledge/manager.py +251 -74
  39. src/knowledge/progress_tracker.py +43 -2
  40. src/knowledge/start_kb.py +11 -2
  41. src/logging/__init__.py +5 -0
  42. src/logging/adapters/__init__.py +1 -0
  43. src/logging/adapters/lightrag.py +25 -18
  44. src/logging/adapters/llamaindex.py +1 -0
  45. src/logging/config.py +30 -27
  46. src/logging/handlers/__init__.py +1 -0
  47. src/logging/handlers/console.py +7 -50
  48. src/logging/handlers/file.py +5 -20
  49. src/logging/handlers/websocket.py +23 -19
  50. src/logging/logger.py +161 -126
  51. src/logging/stats/__init__.py +1 -0
  52. src/logging/stats/llm_stats.py +37 -17
  53. src/services/__init__.py +17 -1
  54. src/services/config/__init__.py +1 -0
  55. src/services/config/knowledge_base_config.py +1 -0
  56. src/services/config/loader.py +1 -1
  57. src/services/config/unified_config.py +211 -4
  58. src/services/embedding/__init__.py +1 -0
  59. src/services/embedding/adapters/__init__.py +3 -0
  60. src/services/embedding/adapters/base.py +1 -0
  61. src/services/embedding/adapters/cohere.py +1 -0
  62. src/services/embedding/adapters/jina.py +1 -0
  63. src/services/embedding/adapters/ollama.py +1 -0
  64. src/services/embedding/adapters/openai_compatible.py +1 -0
  65. src/services/embedding/adapters/realtimex.py +125 -0
  66. src/services/embedding/client.py +27 -0
  67. src/services/embedding/config.py +3 -0
  68. src/services/embedding/provider.py +1 -0
  69. src/services/llm/__init__.py +17 -3
  70. src/services/llm/capabilities.py +47 -0
  71. src/services/llm/client.py +32 -0
  72. src/services/llm/cloud_provider.py +21 -4
  73. src/services/llm/config.py +36 -2
  74. src/services/llm/error_mapping.py +1 -0
  75. src/services/llm/exceptions.py +30 -0
  76. src/services/llm/factory.py +55 -16
  77. src/services/llm/local_provider.py +1 -0
  78. src/services/llm/providers/anthropic.py +1 -0
  79. src/services/llm/providers/base_provider.py +1 -0
  80. src/services/llm/providers/open_ai.py +1 -0
  81. src/services/llm/realtimex_provider.py +240 -0
  82. src/services/llm/registry.py +1 -0
  83. src/services/llm/telemetry.py +1 -0
  84. src/services/llm/types.py +1 -0
  85. src/services/llm/utils.py +1 -0
  86. src/services/prompt/__init__.py +1 -0
  87. src/services/prompt/manager.py +3 -2
  88. src/services/rag/__init__.py +27 -5
  89. src/services/rag/components/__init__.py +1 -0
  90. src/services/rag/components/base.py +1 -0
  91. src/services/rag/components/chunkers/__init__.py +1 -0
  92. src/services/rag/components/chunkers/base.py +1 -0
  93. src/services/rag/components/chunkers/fixed.py +1 -0
  94. src/services/rag/components/chunkers/numbered_item.py +1 -0
  95. src/services/rag/components/chunkers/semantic.py +1 -0
  96. src/services/rag/components/embedders/__init__.py +1 -0
  97. src/services/rag/components/embedders/base.py +1 -0
  98. src/services/rag/components/embedders/openai.py +1 -0
  99. src/services/rag/components/indexers/__init__.py +1 -0
  100. src/services/rag/components/indexers/base.py +1 -0
  101. src/services/rag/components/indexers/graph.py +5 -44
  102. src/services/rag/components/indexers/lightrag.py +5 -44
  103. src/services/rag/components/indexers/vector.py +1 -0
  104. src/services/rag/components/parsers/__init__.py +1 -0
  105. src/services/rag/components/parsers/base.py +1 -0
  106. src/services/rag/components/parsers/markdown.py +1 -0
  107. src/services/rag/components/parsers/pdf.py +1 -0
  108. src/services/rag/components/parsers/text.py +1 -0
  109. src/services/rag/components/retrievers/__init__.py +1 -0
  110. src/services/rag/components/retrievers/base.py +1 -0
  111. src/services/rag/components/retrievers/dense.py +1 -0
  112. src/services/rag/components/retrievers/hybrid.py +5 -44
  113. src/services/rag/components/retrievers/lightrag.py +5 -44
  114. src/services/rag/components/routing.py +48 -0
  115. src/services/rag/factory.py +112 -46
  116. src/services/rag/pipeline.py +1 -0
  117. src/services/rag/pipelines/__init__.py +27 -18
  118. src/services/rag/pipelines/lightrag.py +1 -0
  119. src/services/rag/pipelines/llamaindex.py +99 -0
  120. src/services/rag/pipelines/raganything.py +67 -100
  121. src/services/rag/pipelines/raganything_docling.py +368 -0
  122. src/services/rag/service.py +5 -12
  123. src/services/rag/types.py +1 -0
  124. src/services/rag/utils/__init__.py +17 -0
  125. src/services/rag/utils/image_migration.py +279 -0
  126. src/services/search/__init__.py +1 -0
  127. src/services/search/base.py +1 -0
  128. src/services/search/consolidation.py +1 -0
  129. src/services/search/providers/__init__.py +1 -0
  130. src/services/search/providers/baidu.py +1 -0
  131. src/services/search/providers/exa.py +1 -0
  132. src/services/search/providers/jina.py +1 -0
  133. src/services/search/providers/perplexity.py +1 -0
  134. src/services/search/providers/serper.py +1 -0
  135. src/services/search/providers/tavily.py +1 -0
  136. src/services/search/types.py +1 -0
  137. src/services/settings/__init__.py +1 -0
  138. src/services/settings/interface_settings.py +78 -0
  139. src/services/setup/__init__.py +1 -0
  140. src/services/tts/__init__.py +1 -0
  141. src/services/tts/config.py +1 -0
  142. src/utils/realtimex.py +284 -0
  143. realtimex_deeptutor-0.5.0.post1.dist-info/entry_points.txt +0 -2
  144. src/services/rag/pipelines/academic.py +0 -44
  145. {realtimex_deeptutor-0.5.0.post1.dist-info → realtimex_deeptutor-0.5.0.post3.dist-info}/licenses/LICENSE +0 -0
src/cli/start.py ADDED
@@ -0,0 +1,209 @@
1
+ """
2
+ Unified startup entry point for DeepTutor.
3
+
4
+ Design Philosophy:
5
+ - Configuration over code: Behavior driven by config files + CLI args
6
+ - Fail fast: Validate early with actionable error messages
7
+ - Extensible: Easy to add new modes and commands
8
+ - Maintainable: Clean separation between CLI and core logic
9
+
10
+ Usage:
11
+ uvx realtimex-deeptutor # Start with defaults
12
+ uvx realtimex-deeptutor --port 4001 # Custom frontend port
13
+ uvx realtimex-deeptutor --backend-only # Backend only (future)
14
+ """
15
+
16
+ import argparse
17
+ import os
18
+ from pathlib import Path
19
+ import subprocess
20
+ import sys
21
+
22
+
23
+ def create_parser() -> argparse.ArgumentParser:
24
+ """
25
+ Create CLI argument parser following Unix conventions.
26
+
27
+ Design: Minimal CLI options, environment-driven configuration.
28
+ """
29
+ parser = argparse.ArgumentParser(
30
+ prog="realtimex-deeptutor",
31
+ description="DeepTutor - AI-Powered Personalized Learning Assistant",
32
+ formatter_class=argparse.RawDescriptionHelpFormatter,
33
+ epilog="""
34
+ Examples:
35
+ uvx realtimex-deeptutor # Start with defaults
36
+ FRONTEND_PORT=4001 uvx realtimex-deeptutor # Custom frontend port
37
+ BACKEND_PORT=8002 uvx realtimex-deeptutor # Custom backend port
38
+
39
+ Environment Variables:
40
+ FRONTEND_PORT Frontend port (default: 3782)
41
+ BACKEND_PORT Backend port (default: 8001)
42
+ RTX_APP_ID RealTimeX App ID (auto-detected)
43
+ API_BASE_URL Backend API URL (auto-configured)
44
+ LOG_LEVEL Logging level (DEBUG, INFO, WARNING, ERROR)
45
+
46
+ For more information: https://github.com/therealtimex/DeepTutor-local-app
47
+ """,
48
+ )
49
+
50
+ # Mode selection (future extensibility)
51
+ mode_group = parser.add_mutually_exclusive_group()
52
+ mode_group.add_argument(
53
+ "--backend-only",
54
+ action="store_true",
55
+ help="Start backend only (FastAPI) [NOT YET IMPLEMENTED]",
56
+ )
57
+ mode_group.add_argument(
58
+ "--frontend-only",
59
+ action="store_true",
60
+ help="Start frontend only (Next.js) [NOT YET IMPLEMENTED]",
61
+ )
62
+
63
+ # Logging configuration
64
+ parser.add_argument(
65
+ "--log-level",
66
+ choices=["DEBUG", "INFO", "WARNING", "ERROR"],
67
+ default=os.getenv("LOG_LEVEL", "INFO"),
68
+ help="Logging level (default: INFO)",
69
+ )
70
+
71
+ return parser
72
+
73
+
74
+ def find_project_root() -> Path:
75
+ """
76
+ Find DeepTutor project root directory.
77
+
78
+ Strategy:
79
+ 1. Use __file__ location (works for both installed and development)
80
+ 2. Fall back to pyproject.toml search for development mode
81
+
82
+ Returns:
83
+ Path: Absolute path to project root
84
+
85
+ Raises:
86
+ RuntimeError: If project root cannot be determined
87
+ """
88
+ # Primary strategy: Use __file__ location
89
+ # This file is at: <root>/src/cli/start.py
90
+ # So root is 3 levels up: start.py -> cli -> src -> root
91
+ package_root = Path(__file__).resolve().parent.parent.parent
92
+
93
+ # Validate by checking for essential package content (not pyproject.toml)
94
+ if (package_root / "src" / "api").is_dir():
95
+ return package_root
96
+
97
+ # Fallback: Development mode - look for pyproject.toml
98
+ for parent in Path(__file__).resolve().parents:
99
+ if (parent / "pyproject.toml").exists():
100
+ return parent
101
+
102
+ # Last fallback: return computed root without strict validation
103
+ # This allows the package to attempt startup even if structure is unusual
104
+ return package_root
105
+
106
+
107
+ def validate_environment(project_root: Path) -> None:
108
+ """
109
+ Validate environment and dependencies.
110
+
111
+ Args:
112
+ project_root: Path to project root
113
+
114
+ Raises:
115
+ RuntimeError: If validation fails
116
+ """
117
+ # Check for start_web.py
118
+ start_script = project_root / "scripts" / "start_web.py"
119
+ if not start_script.exists():
120
+ raise RuntimeError(
121
+ f"Required script not found: {start_script}\n"
122
+ f"Project root: {project_root}\n"
123
+ "Please ensure DeepTutor is properly installed."
124
+ )
125
+
126
+ # Check for web directory only in development mode
127
+ # In production mode, frontend is served via npx @realtimex/opentutor-web
128
+ dev_mode = os.environ.get("FRONTEND_DEV_MODE", "").lower() in ("true", "1", "yes")
129
+ if dev_mode:
130
+ web_dir = project_root / "web"
131
+ if not web_dir.exists():
132
+ raise RuntimeError(
133
+ f"Frontend directory not found: {web_dir}\n"
134
+ "FRONTEND_DEV_MODE is enabled but web/ directory is missing.\n"
135
+ "Either disable dev mode or run from the project source directory."
136
+ )
137
+
138
+
139
+ def main():
140
+ """
141
+ Main CLI entry point.
142
+
143
+ Flow:
144
+ 1. Parse arguments
145
+ 2. Find and validate project root
146
+ 3. Build environment
147
+ 4. Delegate to appropriate launcher
148
+ """
149
+ parser = create_parser()
150
+ args = parser.parse_args()
151
+
152
+ try:
153
+ # Find project root
154
+ project_root = find_project_root()
155
+
156
+ # Validate environment
157
+ validate_environment(project_root)
158
+
159
+ # Build environment for subprocess
160
+ # All configuration comes from environment variables
161
+ env = os.environ.copy()
162
+
163
+ # Set log level
164
+ env["LOG_LEVEL"] = args.log_level
165
+
166
+ # Handle mode selection
167
+ if args.backend_only:
168
+ print("⚠️ Backend-only mode not yet implemented")
169
+ print(" Use 'uvx realtimex-deeptutor' for full-stack startup")
170
+ print(" Or use 'deeptutor-backend' for backend-only")
171
+ sys.exit(1)
172
+
173
+ if args.frontend_only:
174
+ print("⚠️ Frontend-only mode not yet implemented")
175
+ print(" Use 'uvx realtimex-deeptutor' for full-stack startup")
176
+ print(" Or use 'npx @realtimex/opentutor-web' for frontend-only")
177
+ sys.exit(1)
178
+
179
+ # Full-stack mode: delegate to start_web.py
180
+ print("🚀 Starting DeepTutor (Full Stack)...")
181
+ print(f"📁 Project root: {project_root}")
182
+
183
+ script_path = project_root / "scripts" / "start_web.py"
184
+
185
+ # Launch start_web.py with updated environment
186
+ subprocess.run([sys.executable, str(script_path)], env=env, cwd=project_root, check=True)
187
+
188
+ except KeyboardInterrupt:
189
+ print("\n🛑 Shutting down...")
190
+ sys.exit(0)
191
+
192
+ except RuntimeError as e:
193
+ print(f"❌ Error: {e}", file=sys.stderr)
194
+ sys.exit(1)
195
+
196
+ except subprocess.CalledProcessError as e:
197
+ # start_web.py already printed error messages
198
+ sys.exit(e.returncode)
199
+
200
+ except Exception as e:
201
+ print(f"❌ Unexpected error: {e}", file=sys.stderr)
202
+ import traceback
203
+
204
+ traceback.print_exc()
205
+ sys.exit(1)
206
+
207
+
208
+ if __name__ == "__main__":
209
+ main()
src/config/constants.py CHANGED
@@ -23,12 +23,14 @@ VALID_SOLVE_TOOLS = [
23
23
  "finish",
24
24
  ]
25
25
 
26
- # Logging symbols for different log levels
27
- LOG_SYMBOLS = {
28
- "DEBUG": "·",
29
- "INFO": "●",
30
- "SUCCESS": "✓",
31
- "WARNING": "⚠",
32
- "ERROR": "✗",
33
- "CRITICAL": "✗",
34
- }
26
+ # Standard log level tags (used in unified logging format)
27
+ LOG_LEVEL_TAGS = [
28
+ "DEBUG",
29
+ "INFO",
30
+ "SUCCESS",
31
+ "WARNING",
32
+ "ERROR",
33
+ "CRITICAL",
34
+ "PROGRESS",
35
+ "COMPLETE",
36
+ ]