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.
- {realtimex_deeptutor-0.5.0.post1.dist-info → realtimex_deeptutor-0.5.0.post3.dist-info}/METADATA +24 -17
- {realtimex_deeptutor-0.5.0.post1.dist-info → realtimex_deeptutor-0.5.0.post3.dist-info}/RECORD +143 -123
- {realtimex_deeptutor-0.5.0.post1.dist-info → realtimex_deeptutor-0.5.0.post3.dist-info}/WHEEL +1 -1
- realtimex_deeptutor-0.5.0.post3.dist-info/entry_points.txt +4 -0
- {realtimex_deeptutor-0.5.0.post1.dist-info → realtimex_deeptutor-0.5.0.post3.dist-info}/top_level.txt +1 -0
- scripts/__init__.py +1 -0
- scripts/audit_prompts.py +179 -0
- scripts/check_install.py +460 -0
- scripts/generate_roster.py +327 -0
- scripts/install_all.py +653 -0
- scripts/migrate_kb.py +655 -0
- scripts/start.py +807 -0
- scripts/start_web.py +632 -0
- scripts/sync_prompts_from_en.py +147 -0
- src/__init__.py +2 -2
- src/agents/ideagen/material_organizer_agent.py +2 -0
- src/agents/solve/__init__.py +6 -0
- src/agents/solve/main_solver.py +9 -0
- src/agents/solve/prompts/zh/analysis_loop/investigate_agent.yaml +9 -7
- src/agents/solve/session_manager.py +345 -0
- src/api/main.py +14 -0
- src/api/routers/chat.py +3 -3
- src/api/routers/co_writer.py +12 -7
- src/api/routers/config.py +1 -0
- src/api/routers/guide.py +3 -1
- src/api/routers/ideagen.py +7 -0
- src/api/routers/knowledge.py +64 -12
- src/api/routers/question.py +2 -0
- src/api/routers/realtimex.py +137 -0
- src/api/routers/research.py +9 -0
- src/api/routers/solve.py +120 -2
- src/cli/__init__.py +13 -0
- src/cli/start.py +209 -0
- src/config/constants.py +11 -9
- src/knowledge/add_documents.py +453 -213
- src/knowledge/extract_numbered_items.py +9 -10
- src/knowledge/initializer.py +102 -101
- src/knowledge/manager.py +251 -74
- src/knowledge/progress_tracker.py +43 -2
- src/knowledge/start_kb.py +11 -2
- src/logging/__init__.py +5 -0
- src/logging/adapters/__init__.py +1 -0
- src/logging/adapters/lightrag.py +25 -18
- src/logging/adapters/llamaindex.py +1 -0
- src/logging/config.py +30 -27
- src/logging/handlers/__init__.py +1 -0
- src/logging/handlers/console.py +7 -50
- src/logging/handlers/file.py +5 -20
- src/logging/handlers/websocket.py +23 -19
- src/logging/logger.py +161 -126
- src/logging/stats/__init__.py +1 -0
- src/logging/stats/llm_stats.py +37 -17
- src/services/__init__.py +17 -1
- src/services/config/__init__.py +1 -0
- src/services/config/knowledge_base_config.py +1 -0
- src/services/config/loader.py +1 -1
- src/services/config/unified_config.py +211 -4
- src/services/embedding/__init__.py +1 -0
- src/services/embedding/adapters/__init__.py +3 -0
- src/services/embedding/adapters/base.py +1 -0
- src/services/embedding/adapters/cohere.py +1 -0
- src/services/embedding/adapters/jina.py +1 -0
- src/services/embedding/adapters/ollama.py +1 -0
- src/services/embedding/adapters/openai_compatible.py +1 -0
- src/services/embedding/adapters/realtimex.py +125 -0
- src/services/embedding/client.py +27 -0
- src/services/embedding/config.py +3 -0
- src/services/embedding/provider.py +1 -0
- src/services/llm/__init__.py +17 -3
- src/services/llm/capabilities.py +47 -0
- src/services/llm/client.py +32 -0
- src/services/llm/cloud_provider.py +21 -4
- src/services/llm/config.py +36 -2
- src/services/llm/error_mapping.py +1 -0
- src/services/llm/exceptions.py +30 -0
- src/services/llm/factory.py +55 -16
- src/services/llm/local_provider.py +1 -0
- src/services/llm/providers/anthropic.py +1 -0
- src/services/llm/providers/base_provider.py +1 -0
- src/services/llm/providers/open_ai.py +1 -0
- src/services/llm/realtimex_provider.py +240 -0
- src/services/llm/registry.py +1 -0
- src/services/llm/telemetry.py +1 -0
- src/services/llm/types.py +1 -0
- src/services/llm/utils.py +1 -0
- src/services/prompt/__init__.py +1 -0
- src/services/prompt/manager.py +3 -2
- src/services/rag/__init__.py +27 -5
- src/services/rag/components/__init__.py +1 -0
- src/services/rag/components/base.py +1 -0
- src/services/rag/components/chunkers/__init__.py +1 -0
- src/services/rag/components/chunkers/base.py +1 -0
- src/services/rag/components/chunkers/fixed.py +1 -0
- src/services/rag/components/chunkers/numbered_item.py +1 -0
- src/services/rag/components/chunkers/semantic.py +1 -0
- src/services/rag/components/embedders/__init__.py +1 -0
- src/services/rag/components/embedders/base.py +1 -0
- src/services/rag/components/embedders/openai.py +1 -0
- src/services/rag/components/indexers/__init__.py +1 -0
- src/services/rag/components/indexers/base.py +1 -0
- src/services/rag/components/indexers/graph.py +5 -44
- src/services/rag/components/indexers/lightrag.py +5 -44
- src/services/rag/components/indexers/vector.py +1 -0
- src/services/rag/components/parsers/__init__.py +1 -0
- src/services/rag/components/parsers/base.py +1 -0
- src/services/rag/components/parsers/markdown.py +1 -0
- src/services/rag/components/parsers/pdf.py +1 -0
- src/services/rag/components/parsers/text.py +1 -0
- src/services/rag/components/retrievers/__init__.py +1 -0
- src/services/rag/components/retrievers/base.py +1 -0
- src/services/rag/components/retrievers/dense.py +1 -0
- src/services/rag/components/retrievers/hybrid.py +5 -44
- src/services/rag/components/retrievers/lightrag.py +5 -44
- src/services/rag/components/routing.py +48 -0
- src/services/rag/factory.py +112 -46
- src/services/rag/pipeline.py +1 -0
- src/services/rag/pipelines/__init__.py +27 -18
- src/services/rag/pipelines/lightrag.py +1 -0
- src/services/rag/pipelines/llamaindex.py +99 -0
- src/services/rag/pipelines/raganything.py +67 -100
- src/services/rag/pipelines/raganything_docling.py +368 -0
- src/services/rag/service.py +5 -12
- src/services/rag/types.py +1 -0
- src/services/rag/utils/__init__.py +17 -0
- src/services/rag/utils/image_migration.py +279 -0
- src/services/search/__init__.py +1 -0
- src/services/search/base.py +1 -0
- src/services/search/consolidation.py +1 -0
- src/services/search/providers/__init__.py +1 -0
- src/services/search/providers/baidu.py +1 -0
- src/services/search/providers/exa.py +1 -0
- src/services/search/providers/jina.py +1 -0
- src/services/search/providers/perplexity.py +1 -0
- src/services/search/providers/serper.py +1 -0
- src/services/search/providers/tavily.py +1 -0
- src/services/search/types.py +1 -0
- src/services/settings/__init__.py +1 -0
- src/services/settings/interface_settings.py +78 -0
- src/services/setup/__init__.py +1 -0
- src/services/tts/__init__.py +1 -0
- src/services/tts/config.py +1 -0
- src/utils/realtimex.py +284 -0
- realtimex_deeptutor-0.5.0.post1.dist-info/entry_points.txt +0 -2
- src/services/rag/pipelines/academic.py +0 -44
- {realtimex_deeptutor-0.5.0.post1.dist-info → realtimex_deeptutor-0.5.0.post3.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"""
|
|
2
|
+
RealTimeX LLM Provider
|
|
3
|
+
======================
|
|
4
|
+
|
|
5
|
+
Provides LLM capabilities through RealTimeX SDK proxy.
|
|
6
|
+
Used when running as a local app within RealTimeX desktop.
|
|
7
|
+
|
|
8
|
+
This provider maps DeepTutor's LLM API to the RealTimeX SDK's ChatMessage format
|
|
9
|
+
and handles error translation from SDK exceptions to DeepTutor exception hierarchy.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from typing import TYPE_CHECKING, AsyncGenerator, Dict, List, Optional
|
|
13
|
+
|
|
14
|
+
from src.logging import get_logger
|
|
15
|
+
from src.utils.realtimex import get_realtimex_sdk
|
|
16
|
+
|
|
17
|
+
from .exceptions import LLMAPIError, LLMRateLimitError, RealTimeXError, RealTimeXPermissionError
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from realtimex_sdk import ChatMessage
|
|
21
|
+
|
|
22
|
+
logger = get_logger("RealTimeXProvider")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _build_messages(
|
|
26
|
+
prompt: str,
|
|
27
|
+
system_prompt: str = "You are a helpful assistant.",
|
|
28
|
+
messages: Optional[List[Dict[str, str]]] = None,
|
|
29
|
+
) -> List["ChatMessage"]:
|
|
30
|
+
"""
|
|
31
|
+
Build ChatMessage array from DeepTutor's API parameters.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
prompt: User message
|
|
35
|
+
system_prompt: System role instruction
|
|
36
|
+
messages: Optional pre-built messages array
|
|
37
|
+
|
|
38
|
+
Returns:
|
|
39
|
+
List[ChatMessage]: Messages formatted for SDK
|
|
40
|
+
"""
|
|
41
|
+
from realtimex_sdk import ChatMessage
|
|
42
|
+
|
|
43
|
+
if messages:
|
|
44
|
+
# Convert dict format to ChatMessage objects
|
|
45
|
+
return [ChatMessage(role=m["role"], content=m["content"]) for m in messages]
|
|
46
|
+
else:
|
|
47
|
+
# Build from prompt and system_prompt
|
|
48
|
+
return [
|
|
49
|
+
ChatMessage(role="system", content=system_prompt),
|
|
50
|
+
ChatMessage(role="user", content=prompt),
|
|
51
|
+
]
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def _map_sdk_error(e: Exception) -> Exception:
|
|
55
|
+
"""
|
|
56
|
+
Map SDK exceptions to DeepTutor exception hierarchy.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
e: SDK exception
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
Exception: Mapped DeepTutor exception
|
|
63
|
+
"""
|
|
64
|
+
try:
|
|
65
|
+
from realtimex_sdk import LLMPermissionError, LLMProviderError
|
|
66
|
+
|
|
67
|
+
if isinstance(e, LLMPermissionError):
|
|
68
|
+
return RealTimeXPermissionError(
|
|
69
|
+
permission=e.permission, message=f"RealTimeX permission required: {e.permission}"
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
if isinstance(e, LLMProviderError):
|
|
73
|
+
if e.code == "RATE_LIMIT":
|
|
74
|
+
return LLMRateLimitError(str(e), provider="realtimex")
|
|
75
|
+
if e.code in ("LLM_STREAM_ERROR", "LLM_ERROR"):
|
|
76
|
+
return RealTimeXError(str(e), error_code=e.code)
|
|
77
|
+
|
|
78
|
+
# Generic provider error
|
|
79
|
+
return RealTimeXError(str(e), error_code=e.code)
|
|
80
|
+
|
|
81
|
+
except ImportError:
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
# Fallback for unknown errors
|
|
85
|
+
return LLMAPIError(f"RealTimeX SDK error: {str(e)}", provider="realtimex")
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
async def complete(
|
|
89
|
+
prompt: str,
|
|
90
|
+
system_prompt: str = "You are a helpful assistant.",
|
|
91
|
+
model: Optional[str] = None,
|
|
92
|
+
temperature: float = 0.7,
|
|
93
|
+
max_tokens: int = 1000,
|
|
94
|
+
messages: Optional[List[Dict[str, str]]] = None,
|
|
95
|
+
response_format: Optional[Dict[str, str]] = None,
|
|
96
|
+
**kwargs,
|
|
97
|
+
) -> str:
|
|
98
|
+
"""
|
|
99
|
+
Complete request via RealTimeX SDK.
|
|
100
|
+
|
|
101
|
+
Maps DeepTutor's API to SDK's ChatMessage format and handles error translation.
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
prompt: User message
|
|
105
|
+
system_prompt: System role instruction (default: "You are a helpful assistant.")
|
|
106
|
+
model: Optional model override
|
|
107
|
+
temperature: Sampling temperature (0.0-2.0)
|
|
108
|
+
max_tokens: Maximum tokens to generate
|
|
109
|
+
messages: Optional pre-built messages array
|
|
110
|
+
response_format: Optional response format config (e.g., {"type": "json_object"})
|
|
111
|
+
**kwargs: Additional parameters (ignored for now)
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
str: Generated completion text
|
|
115
|
+
|
|
116
|
+
Raises:
|
|
117
|
+
RealTimeXPermissionError: If permission is required/denied
|
|
118
|
+
RealTimeXError: If SDK request fails
|
|
119
|
+
LLMRateLimitError: If rate limited
|
|
120
|
+
"""
|
|
121
|
+
from realtimex_sdk import ChatOptions
|
|
122
|
+
|
|
123
|
+
sdk = get_realtimex_sdk()
|
|
124
|
+
|
|
125
|
+
# Build messages array
|
|
126
|
+
chat_messages = _build_messages(prompt, system_prompt, messages)
|
|
127
|
+
|
|
128
|
+
# Build options
|
|
129
|
+
options = ChatOptions(
|
|
130
|
+
model=model,
|
|
131
|
+
temperature=temperature,
|
|
132
|
+
max_tokens=max_tokens,
|
|
133
|
+
response_format=response_format, # Pass through to SDK
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Log request
|
|
137
|
+
logger.debug(
|
|
138
|
+
f"RealTimeX complete: model={model or 'default'}, "
|
|
139
|
+
f"temp={temperature}, max_tokens={max_tokens}, "
|
|
140
|
+
f"messages_count={len(chat_messages)}, "
|
|
141
|
+
f"response_format={response_format}"
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
try:
|
|
145
|
+
response = await sdk.llm.chat(chat_messages, options)
|
|
146
|
+
|
|
147
|
+
if not response.success:
|
|
148
|
+
logger.error(f"RealTimeX request failed: {response.error}")
|
|
149
|
+
raise RealTimeXError(response.error or "SDK request failed", error_code=response.code)
|
|
150
|
+
|
|
151
|
+
# Log response metadata
|
|
152
|
+
logger.debug(
|
|
153
|
+
f"RealTimeX response: success={response.success}, "
|
|
154
|
+
f"provider={response.provider}, model={response.model}"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
if response.metrics:
|
|
158
|
+
logger.debug(
|
|
159
|
+
f"Tokens: {response.metrics.total_tokens} "
|
|
160
|
+
f"(prompt={response.metrics.prompt_tokens}, "
|
|
161
|
+
f"completion={response.metrics.completion_tokens})"
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
return response.content or ""
|
|
165
|
+
|
|
166
|
+
except Exception as e:
|
|
167
|
+
# Map SDK errors to DeepTutor exceptions
|
|
168
|
+
mapped_error = _map_sdk_error(e)
|
|
169
|
+
logger.error(f"RealTimeX error: {mapped_error}")
|
|
170
|
+
raise mapped_error
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
async def stream(
|
|
174
|
+
prompt: str,
|
|
175
|
+
system_prompt: str = "You are a helpful assistant.",
|
|
176
|
+
model: Optional[str] = None,
|
|
177
|
+
temperature: float = 0.7,
|
|
178
|
+
max_tokens: int = 1000,
|
|
179
|
+
messages: Optional[List[Dict[str, str]]] = None,
|
|
180
|
+
response_format: Optional[Dict[str, str]] = None,
|
|
181
|
+
**kwargs,
|
|
182
|
+
) -> AsyncGenerator[str, None]:
|
|
183
|
+
"""
|
|
184
|
+
Stream response via RealTimeX SDK.
|
|
185
|
+
|
|
186
|
+
Args:
|
|
187
|
+
prompt: User message
|
|
188
|
+
system_prompt: System role instruction
|
|
189
|
+
model: Optional model override
|
|
190
|
+
temperature: Sampling temperature (0.0-2.0)
|
|
191
|
+
max_tokens: Maximum tokens to generate
|
|
192
|
+
messages: Optional pre-built messages array
|
|
193
|
+
response_format: Optional response format config
|
|
194
|
+
**kwargs: Additional parameters (ignored)
|
|
195
|
+
|
|
196
|
+
Yields:
|
|
197
|
+
str: Text chunks as they arrive
|
|
198
|
+
|
|
199
|
+
Raises:
|
|
200
|
+
RealTimeXPermissionError: If permission is required/denied
|
|
201
|
+
RealTimeXError: If SDK request fails
|
|
202
|
+
LLMRateLimitError: If rate limited
|
|
203
|
+
"""
|
|
204
|
+
from realtimex_sdk import ChatOptions
|
|
205
|
+
|
|
206
|
+
sdk = get_realtimex_sdk()
|
|
207
|
+
|
|
208
|
+
# Build messages array
|
|
209
|
+
chat_messages = _build_messages(prompt, system_prompt, messages)
|
|
210
|
+
|
|
211
|
+
# Build options
|
|
212
|
+
options = ChatOptions(
|
|
213
|
+
model=model,
|
|
214
|
+
temperature=temperature,
|
|
215
|
+
max_tokens=max_tokens,
|
|
216
|
+
response_format=response_format, # Pass through to SDK
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# Log request
|
|
220
|
+
logger.debug(
|
|
221
|
+
f"RealTimeX stream: model={model or 'default'}, "
|
|
222
|
+
f"temp={temperature}, max_tokens={max_tokens}, "
|
|
223
|
+
f"messages_count={len(chat_messages)}, "
|
|
224
|
+
f"response_format={response_format}"
|
|
225
|
+
)
|
|
226
|
+
|
|
227
|
+
try:
|
|
228
|
+
async for chunk in sdk.llm.chat_stream(chat_messages, options):
|
|
229
|
+
if chunk.error:
|
|
230
|
+
logger.error("RealTimeX stream error detected")
|
|
231
|
+
raise RealTimeXError("Stream error", error_code="LLM_STREAM_ERROR")
|
|
232
|
+
|
|
233
|
+
if chunk.text:
|
|
234
|
+
yield chunk.text
|
|
235
|
+
|
|
236
|
+
except Exception as e:
|
|
237
|
+
# Map SDK errors to DeepTutor exceptions
|
|
238
|
+
mapped_error = _map_sdk_error(e)
|
|
239
|
+
logger.error(f"RealTimeX stream error: {mapped_error}")
|
|
240
|
+
raise mapped_error
|
src/services/llm/registry.py
CHANGED
src/services/llm/telemetry.py
CHANGED
src/services/llm/types.py
CHANGED
src/services/llm/utils.py
CHANGED
src/services/prompt/__init__.py
CHANGED
src/services/prompt/manager.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
2
3
|
"""
|
|
3
4
|
Unified Prompt Manager - Single source of truth for all prompt loading.
|
|
4
5
|
Supports multi-language, caching, and language fallbacks.
|
|
@@ -20,8 +21,8 @@ class PromptManager:
|
|
|
20
21
|
|
|
21
22
|
# Language fallback chain: if primary language not found, try alternatives
|
|
22
23
|
LANGUAGE_FALLBACKS = {
|
|
23
|
-
"zh": ["zh", "en"],
|
|
24
|
-
"en": ["en", "zh"],
|
|
24
|
+
"zh": ["zh", "cn", "en"],
|
|
25
|
+
"en": ["en", "zh", "cn"],
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
# Supported modules
|
src/services/rag/__init__.py
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
"""
|
|
2
3
|
RAG Service
|
|
3
4
|
===========
|
|
@@ -7,7 +8,7 @@ Unified RAG pipeline service for DeepTutor.
|
|
|
7
8
|
Provides:
|
|
8
9
|
- RAGService: Unified entry point for all RAG operations
|
|
9
10
|
- Composable RAG pipelines
|
|
10
|
-
- Pre-configured pipelines (RAGAnything, LightRAG, LlamaIndex
|
|
11
|
+
- Pre-configured pipelines (RAGAnything, LightRAG, LlamaIndex)
|
|
11
12
|
- Modular components (parsers, chunkers, embedders, indexers, retrievers)
|
|
12
13
|
- Factory for pipeline creation
|
|
13
14
|
|
|
@@ -39,12 +40,33 @@ Usage:
|
|
|
39
40
|
|
|
40
41
|
from .factory import get_pipeline, has_pipeline, list_pipelines, register_pipeline
|
|
41
42
|
from .pipeline import RAGPipeline
|
|
42
|
-
|
|
43
|
-
# Import pipeline classes for convenience
|
|
44
|
-
from .pipelines.raganything import RAGAnythingPipeline
|
|
45
43
|
from .service import RAGService
|
|
46
44
|
from .types import Chunk, Document, SearchResult
|
|
47
45
|
|
|
46
|
+
|
|
47
|
+
# Lazy import for RAGAnythingPipeline to avoid importing heavy dependencies at module load time
|
|
48
|
+
def __getattr__(name: str):
|
|
49
|
+
"""Lazy import for pipeline classes that depend on heavy libraries."""
|
|
50
|
+
if name == "RAGAnythingPipeline":
|
|
51
|
+
from .pipelines.raganything import RAGAnythingPipeline
|
|
52
|
+
|
|
53
|
+
return RAGAnythingPipeline
|
|
54
|
+
if name == "RAGAnythingDoclingPipeline":
|
|
55
|
+
from .pipelines.raganything_docling import RAGAnythingDoclingPipeline
|
|
56
|
+
|
|
57
|
+
return RAGAnythingDoclingPipeline
|
|
58
|
+
if name == "LlamaIndexPipeline":
|
|
59
|
+
# Optional dependency: llama_index
|
|
60
|
+
from .pipelines.llamaindex import LlamaIndexPipeline
|
|
61
|
+
|
|
62
|
+
return LlamaIndexPipeline
|
|
63
|
+
if name == "LightRAGPipeline":
|
|
64
|
+
from .pipelines.lightrag import LightRAGPipeline
|
|
65
|
+
|
|
66
|
+
return LightRAGPipeline
|
|
67
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
68
|
+
|
|
69
|
+
|
|
48
70
|
__all__ = [
|
|
49
71
|
# Service (recommended entry point)
|
|
50
72
|
"RAGService",
|
|
@@ -59,6 +81,6 @@ __all__ = [
|
|
|
59
81
|
"list_pipelines",
|
|
60
82
|
"register_pipeline",
|
|
61
83
|
"has_pipeline",
|
|
62
|
-
# Pipeline implementations
|
|
84
|
+
# Pipeline implementations (lazy loaded)
|
|
63
85
|
"RAGAnythingPipeline",
|
|
64
86
|
]
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
"""
|
|
2
3
|
Graph Indexer
|
|
3
4
|
=============
|
|
@@ -51,58 +52,18 @@ class GraphIndexer(BaseComponent):
|
|
|
51
52
|
sys.path.insert(0, str(raganything_path))
|
|
52
53
|
|
|
53
54
|
try:
|
|
54
|
-
from openai import AsyncOpenAI
|
|
55
55
|
from raganything import RAGAnything, RAGAnythingConfig
|
|
56
56
|
|
|
57
57
|
from src.services.embedding import get_embedding_client
|
|
58
58
|
from src.services.llm import get_llm_client
|
|
59
59
|
|
|
60
|
+
# Use unified LLM client from src/services/llm
|
|
60
61
|
llm_client = get_llm_client()
|
|
61
62
|
embed_client = get_embedding_client()
|
|
62
63
|
|
|
63
|
-
#
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
base_url=llm_client.config.base_url,
|
|
67
|
-
)
|
|
68
|
-
|
|
69
|
-
# LLM function using services (ASYNC - LightRAG expects async functions)
|
|
70
|
-
async def llm_model_func(prompt, system_prompt=None, history_messages=None, **kwargs):
|
|
71
|
-
"""Custom async LLM function that bypasses LightRAG's openai_complete_if_cache."""
|
|
72
|
-
if history_messages is None:
|
|
73
|
-
history_messages = []
|
|
74
|
-
|
|
75
|
-
# Build messages
|
|
76
|
-
messages = []
|
|
77
|
-
if system_prompt:
|
|
78
|
-
messages.append({"role": "system", "content": system_prompt})
|
|
79
|
-
messages.extend(history_messages)
|
|
80
|
-
messages.append({"role": "user", "content": prompt})
|
|
81
|
-
|
|
82
|
-
# Whitelist only valid OpenAI parameters
|
|
83
|
-
valid_params = {
|
|
84
|
-
"temperature",
|
|
85
|
-
"top_p",
|
|
86
|
-
"n",
|
|
87
|
-
"stream",
|
|
88
|
-
"stop",
|
|
89
|
-
"max_tokens",
|
|
90
|
-
"presence_penalty",
|
|
91
|
-
"frequency_penalty",
|
|
92
|
-
"logit_bias",
|
|
93
|
-
"user",
|
|
94
|
-
"seed",
|
|
95
|
-
}
|
|
96
|
-
clean_kwargs = {k: v for k, v in kwargs.items() if k in valid_params}
|
|
97
|
-
|
|
98
|
-
# Call OpenAI API directly (async)
|
|
99
|
-
response = await openai_client.chat.completions.create(
|
|
100
|
-
model=llm_client.config.model,
|
|
101
|
-
messages=messages,
|
|
102
|
-
**clean_kwargs,
|
|
103
|
-
)
|
|
104
|
-
|
|
105
|
-
return response.choices[0].message.content
|
|
64
|
+
# Get model function from unified LLM client
|
|
65
|
+
# This handles all provider differences and env var setup for LightRAG
|
|
66
|
+
llm_model_func = llm_client.get_model_func()
|
|
106
67
|
|
|
107
68
|
config = RAGAnythingConfig(
|
|
108
69
|
working_dir=working_dir,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
"""
|
|
2
3
|
LightRAG Indexer
|
|
3
4
|
================
|
|
@@ -53,57 +54,17 @@ class LightRAGIndexer(BaseComponent):
|
|
|
53
54
|
|
|
54
55
|
try:
|
|
55
56
|
from lightrag import LightRAG
|
|
56
|
-
from openai import AsyncOpenAI
|
|
57
57
|
|
|
58
58
|
from src.services.embedding import get_embedding_client
|
|
59
59
|
from src.services.llm import get_llm_client
|
|
60
60
|
|
|
61
|
+
# Use unified LLM client from src/services/llm
|
|
61
62
|
llm_client = get_llm_client()
|
|
62
63
|
embed_client = get_embedding_client()
|
|
63
64
|
|
|
64
|
-
#
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
base_url=llm_client.config.base_url,
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
# LLM function using services (ASYNC - LightRAG expects async functions)
|
|
71
|
-
async def llm_model_func(prompt, system_prompt=None, history_messages=None, **kwargs):
|
|
72
|
-
"""Custom async LLM function that bypasses LightRAG's openai_complete_if_cache."""
|
|
73
|
-
if history_messages is None:
|
|
74
|
-
history_messages = []
|
|
75
|
-
|
|
76
|
-
# Build messages
|
|
77
|
-
messages = []
|
|
78
|
-
if system_prompt:
|
|
79
|
-
messages.append({"role": "system", "content": system_prompt})
|
|
80
|
-
messages.extend(history_messages)
|
|
81
|
-
messages.append({"role": "user", "content": prompt})
|
|
82
|
-
|
|
83
|
-
# Whitelist only valid OpenAI parameters
|
|
84
|
-
valid_params = {
|
|
85
|
-
"temperature",
|
|
86
|
-
"top_p",
|
|
87
|
-
"n",
|
|
88
|
-
"stream",
|
|
89
|
-
"stop",
|
|
90
|
-
"max_tokens",
|
|
91
|
-
"presence_penalty",
|
|
92
|
-
"frequency_penalty",
|
|
93
|
-
"logit_bias",
|
|
94
|
-
"user",
|
|
95
|
-
"seed",
|
|
96
|
-
}
|
|
97
|
-
clean_kwargs = {k: v for k, v in kwargs.items() if k in valid_params}
|
|
98
|
-
|
|
99
|
-
# Call OpenAI API directly (async)
|
|
100
|
-
response = await openai_client.chat.completions.create(
|
|
101
|
-
model=llm_client.config.model,
|
|
102
|
-
messages=messages,
|
|
103
|
-
**clean_kwargs,
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
return response.choices[0].message.content
|
|
65
|
+
# Get model function from unified LLM client
|
|
66
|
+
# This handles all provider differences and env var setup for LightRAG
|
|
67
|
+
llm_model_func = llm_client.get_model_func()
|
|
107
68
|
|
|
108
69
|
# Create pure LightRAG instance (no multimodal)
|
|
109
70
|
rag = LightRAG(
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
1
2
|
"""
|
|
2
3
|
Hybrid Retriever
|
|
3
4
|
================
|
|
@@ -50,58 +51,18 @@ class HybridRetriever(BaseComponent):
|
|
|
50
51
|
sys.path.insert(0, str(raganything_path))
|
|
51
52
|
|
|
52
53
|
try:
|
|
53
|
-
from openai import AsyncOpenAI
|
|
54
54
|
from raganything import RAGAnything, RAGAnythingConfig
|
|
55
55
|
|
|
56
56
|
from src.services.embedding import get_embedding_client
|
|
57
57
|
from src.services.llm import get_llm_client
|
|
58
58
|
|
|
59
|
+
# Use unified LLM client from src/services/llm
|
|
59
60
|
llm_client = get_llm_client()
|
|
60
61
|
embed_client = get_embedding_client()
|
|
61
62
|
|
|
62
|
-
#
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
base_url=llm_client.config.base_url,
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
# LLM function using services (ASYNC - LightRAG expects async functions)
|
|
69
|
-
async def llm_model_func(prompt, system_prompt=None, history_messages=None, **kwargs):
|
|
70
|
-
"""Custom async LLM function that bypasses LightRAG's openai_complete_if_cache."""
|
|
71
|
-
if history_messages is None:
|
|
72
|
-
history_messages = []
|
|
73
|
-
|
|
74
|
-
# Build messages
|
|
75
|
-
messages = []
|
|
76
|
-
if system_prompt:
|
|
77
|
-
messages.append({"role": "system", "content": system_prompt})
|
|
78
|
-
messages.extend(history_messages)
|
|
79
|
-
messages.append({"role": "user", "content": prompt})
|
|
80
|
-
|
|
81
|
-
# Whitelist only valid OpenAI parameters
|
|
82
|
-
valid_params = {
|
|
83
|
-
"temperature",
|
|
84
|
-
"top_p",
|
|
85
|
-
"n",
|
|
86
|
-
"stream",
|
|
87
|
-
"stop",
|
|
88
|
-
"max_tokens",
|
|
89
|
-
"presence_penalty",
|
|
90
|
-
"frequency_penalty",
|
|
91
|
-
"logit_bias",
|
|
92
|
-
"user",
|
|
93
|
-
"seed",
|
|
94
|
-
}
|
|
95
|
-
clean_kwargs = {k: v for k, v in kwargs.items() if k in valid_params}
|
|
96
|
-
|
|
97
|
-
# Call OpenAI API directly (async)
|
|
98
|
-
response = await openai_client.chat.completions.create(
|
|
99
|
-
model=llm_client.config.model,
|
|
100
|
-
messages=messages,
|
|
101
|
-
**clean_kwargs,
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
return response.choices[0].message.content
|
|
63
|
+
# Get model function from unified LLM client
|
|
64
|
+
# This handles all provider differences and env var setup for LightRAG
|
|
65
|
+
llm_model_func = llm_client.get_model_func()
|
|
105
66
|
|
|
106
67
|
config = RAGAnythingConfig(
|
|
107
68
|
working_dir=working_dir,
|