realtimex-deeptutor 0.5.0.post1__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/__init__.py +67 -0
- realtimex_deeptutor-0.5.0.post1.dist-info/METADATA +1612 -0
- realtimex_deeptutor-0.5.0.post1.dist-info/RECORD +276 -0
- realtimex_deeptutor-0.5.0.post1.dist-info/WHEEL +5 -0
- realtimex_deeptutor-0.5.0.post1.dist-info/entry_points.txt +2 -0
- realtimex_deeptutor-0.5.0.post1.dist-info/licenses/LICENSE +661 -0
- realtimex_deeptutor-0.5.0.post1.dist-info/top_level.txt +2 -0
- src/__init__.py +40 -0
- src/agents/__init__.py +24 -0
- src/agents/base_agent.py +657 -0
- src/agents/chat/__init__.py +24 -0
- src/agents/chat/chat_agent.py +435 -0
- src/agents/chat/prompts/en/chat_agent.yaml +35 -0
- src/agents/chat/prompts/zh/chat_agent.yaml +35 -0
- src/agents/chat/session_manager.py +311 -0
- src/agents/co_writer/__init__.py +0 -0
- src/agents/co_writer/edit_agent.py +260 -0
- src/agents/co_writer/narrator_agent.py +423 -0
- src/agents/co_writer/prompts/en/edit_agent.yaml +113 -0
- src/agents/co_writer/prompts/en/narrator_agent.yaml +88 -0
- src/agents/co_writer/prompts/zh/edit_agent.yaml +113 -0
- src/agents/co_writer/prompts/zh/narrator_agent.yaml +88 -0
- src/agents/guide/__init__.py +16 -0
- src/agents/guide/agents/__init__.py +11 -0
- src/agents/guide/agents/chat_agent.py +104 -0
- src/agents/guide/agents/interactive_agent.py +223 -0
- src/agents/guide/agents/locate_agent.py +149 -0
- src/agents/guide/agents/summary_agent.py +150 -0
- src/agents/guide/guide_manager.py +500 -0
- src/agents/guide/prompts/en/chat_agent.yaml +41 -0
- src/agents/guide/prompts/en/interactive_agent.yaml +202 -0
- src/agents/guide/prompts/en/locate_agent.yaml +68 -0
- src/agents/guide/prompts/en/summary_agent.yaml +157 -0
- src/agents/guide/prompts/zh/chat_agent.yaml +41 -0
- src/agents/guide/prompts/zh/interactive_agent.yaml +626 -0
- src/agents/guide/prompts/zh/locate_agent.yaml +68 -0
- src/agents/guide/prompts/zh/summary_agent.yaml +157 -0
- src/agents/ideagen/__init__.py +12 -0
- src/agents/ideagen/idea_generation_workflow.py +426 -0
- src/agents/ideagen/material_organizer_agent.py +173 -0
- src/agents/ideagen/prompts/en/idea_generation.yaml +187 -0
- src/agents/ideagen/prompts/en/material_organizer.yaml +69 -0
- src/agents/ideagen/prompts/zh/idea_generation.yaml +187 -0
- src/agents/ideagen/prompts/zh/material_organizer.yaml +69 -0
- src/agents/question/__init__.py +24 -0
- src/agents/question/agents/__init__.py +18 -0
- src/agents/question/agents/generate_agent.py +381 -0
- src/agents/question/agents/relevance_analyzer.py +207 -0
- src/agents/question/agents/retrieve_agent.py +239 -0
- src/agents/question/coordinator.py +718 -0
- src/agents/question/example.py +109 -0
- src/agents/question/prompts/en/coordinator.yaml +75 -0
- src/agents/question/prompts/en/generate_agent.yaml +77 -0
- src/agents/question/prompts/en/relevance_analyzer.yaml +41 -0
- src/agents/question/prompts/en/retrieve_agent.yaml +32 -0
- src/agents/question/prompts/zh/coordinator.yaml +75 -0
- src/agents/question/prompts/zh/generate_agent.yaml +77 -0
- src/agents/question/prompts/zh/relevance_analyzer.yaml +39 -0
- src/agents/question/prompts/zh/retrieve_agent.yaml +30 -0
- src/agents/research/agents/__init__.py +23 -0
- src/agents/research/agents/decompose_agent.py +507 -0
- src/agents/research/agents/manager_agent.py +228 -0
- src/agents/research/agents/note_agent.py +180 -0
- src/agents/research/agents/rephrase_agent.py +263 -0
- src/agents/research/agents/reporting_agent.py +1333 -0
- src/agents/research/agents/research_agent.py +714 -0
- src/agents/research/data_structures.py +451 -0
- src/agents/research/main.py +188 -0
- src/agents/research/prompts/en/decompose_agent.yaml +89 -0
- src/agents/research/prompts/en/manager_agent.yaml +24 -0
- src/agents/research/prompts/en/note_agent.yaml +121 -0
- src/agents/research/prompts/en/rephrase_agent.yaml +58 -0
- src/agents/research/prompts/en/reporting_agent.yaml +380 -0
- src/agents/research/prompts/en/research_agent.yaml +173 -0
- src/agents/research/prompts/zh/decompose_agent.yaml +89 -0
- src/agents/research/prompts/zh/manager_agent.yaml +24 -0
- src/agents/research/prompts/zh/note_agent.yaml +121 -0
- src/agents/research/prompts/zh/rephrase_agent.yaml +58 -0
- src/agents/research/prompts/zh/reporting_agent.yaml +380 -0
- src/agents/research/prompts/zh/research_agent.yaml +173 -0
- src/agents/research/research_pipeline.py +1309 -0
- src/agents/research/utils/__init__.py +60 -0
- src/agents/research/utils/citation_manager.py +799 -0
- src/agents/research/utils/json_utils.py +98 -0
- src/agents/research/utils/token_tracker.py +297 -0
- src/agents/solve/__init__.py +80 -0
- src/agents/solve/analysis_loop/__init__.py +14 -0
- src/agents/solve/analysis_loop/investigate_agent.py +414 -0
- src/agents/solve/analysis_loop/note_agent.py +190 -0
- src/agents/solve/main_solver.py +862 -0
- src/agents/solve/memory/__init__.py +34 -0
- src/agents/solve/memory/citation_memory.py +353 -0
- src/agents/solve/memory/investigate_memory.py +226 -0
- src/agents/solve/memory/solve_memory.py +340 -0
- src/agents/solve/prompts/en/analysis_loop/investigate_agent.yaml +55 -0
- src/agents/solve/prompts/en/analysis_loop/note_agent.yaml +54 -0
- src/agents/solve/prompts/en/solve_loop/manager_agent.yaml +67 -0
- src/agents/solve/prompts/en/solve_loop/precision_answer_agent.yaml +62 -0
- src/agents/solve/prompts/en/solve_loop/response_agent.yaml +90 -0
- src/agents/solve/prompts/en/solve_loop/solve_agent.yaml +75 -0
- src/agents/solve/prompts/en/solve_loop/tool_agent.yaml +38 -0
- src/agents/solve/prompts/zh/analysis_loop/investigate_agent.yaml +53 -0
- src/agents/solve/prompts/zh/analysis_loop/note_agent.yaml +54 -0
- src/agents/solve/prompts/zh/solve_loop/manager_agent.yaml +66 -0
- src/agents/solve/prompts/zh/solve_loop/precision_answer_agent.yaml +62 -0
- src/agents/solve/prompts/zh/solve_loop/response_agent.yaml +90 -0
- src/agents/solve/prompts/zh/solve_loop/solve_agent.yaml +76 -0
- src/agents/solve/prompts/zh/solve_loop/tool_agent.yaml +41 -0
- src/agents/solve/solve_loop/__init__.py +22 -0
- src/agents/solve/solve_loop/citation_manager.py +74 -0
- src/agents/solve/solve_loop/manager_agent.py +274 -0
- src/agents/solve/solve_loop/precision_answer_agent.py +96 -0
- src/agents/solve/solve_loop/response_agent.py +301 -0
- src/agents/solve/solve_loop/solve_agent.py +325 -0
- src/agents/solve/solve_loop/tool_agent.py +470 -0
- src/agents/solve/utils/__init__.py +64 -0
- src/agents/solve/utils/config_validator.py +313 -0
- src/agents/solve/utils/display_manager.py +223 -0
- src/agents/solve/utils/error_handler.py +363 -0
- src/agents/solve/utils/json_utils.py +98 -0
- src/agents/solve/utils/performance_monitor.py +407 -0
- src/agents/solve/utils/token_tracker.py +541 -0
- src/api/__init__.py +0 -0
- src/api/main.py +240 -0
- src/api/routers/__init__.py +1 -0
- src/api/routers/agent_config.py +69 -0
- src/api/routers/chat.py +296 -0
- src/api/routers/co_writer.py +337 -0
- src/api/routers/config.py +627 -0
- src/api/routers/dashboard.py +18 -0
- src/api/routers/guide.py +337 -0
- src/api/routers/ideagen.py +436 -0
- src/api/routers/knowledge.py +821 -0
- src/api/routers/notebook.py +247 -0
- src/api/routers/question.py +537 -0
- src/api/routers/research.py +394 -0
- src/api/routers/settings.py +164 -0
- src/api/routers/solve.py +305 -0
- src/api/routers/system.py +252 -0
- src/api/run_server.py +61 -0
- src/api/utils/history.py +172 -0
- src/api/utils/log_interceptor.py +21 -0
- src/api/utils/notebook_manager.py +415 -0
- src/api/utils/progress_broadcaster.py +72 -0
- src/api/utils/task_id_manager.py +100 -0
- src/config/__init__.py +0 -0
- src/config/accessors.py +18 -0
- src/config/constants.py +34 -0
- src/config/defaults.py +18 -0
- src/config/schema.py +38 -0
- src/config/settings.py +50 -0
- src/core/errors.py +62 -0
- src/knowledge/__init__.py +23 -0
- src/knowledge/add_documents.py +606 -0
- src/knowledge/config.py +65 -0
- src/knowledge/example_add_documents.py +236 -0
- src/knowledge/extract_numbered_items.py +1039 -0
- src/knowledge/initializer.py +621 -0
- src/knowledge/kb.py +22 -0
- src/knowledge/manager.py +782 -0
- src/knowledge/progress_tracker.py +182 -0
- src/knowledge/start_kb.py +535 -0
- src/logging/__init__.py +103 -0
- src/logging/adapters/__init__.py +17 -0
- src/logging/adapters/lightrag.py +184 -0
- src/logging/adapters/llamaindex.py +141 -0
- src/logging/config.py +80 -0
- src/logging/handlers/__init__.py +20 -0
- src/logging/handlers/console.py +75 -0
- src/logging/handlers/file.py +201 -0
- src/logging/handlers/websocket.py +127 -0
- src/logging/logger.py +709 -0
- src/logging/stats/__init__.py +16 -0
- src/logging/stats/llm_stats.py +179 -0
- src/services/__init__.py +56 -0
- src/services/config/__init__.py +61 -0
- src/services/config/knowledge_base_config.py +210 -0
- src/services/config/loader.py +260 -0
- src/services/config/unified_config.py +603 -0
- src/services/embedding/__init__.py +45 -0
- src/services/embedding/adapters/__init__.py +22 -0
- src/services/embedding/adapters/base.py +106 -0
- src/services/embedding/adapters/cohere.py +127 -0
- src/services/embedding/adapters/jina.py +99 -0
- src/services/embedding/adapters/ollama.py +116 -0
- src/services/embedding/adapters/openai_compatible.py +96 -0
- src/services/embedding/client.py +159 -0
- src/services/embedding/config.py +156 -0
- src/services/embedding/provider.py +119 -0
- src/services/llm/__init__.py +152 -0
- src/services/llm/capabilities.py +313 -0
- src/services/llm/client.py +302 -0
- src/services/llm/cloud_provider.py +530 -0
- src/services/llm/config.py +200 -0
- src/services/llm/error_mapping.py +103 -0
- src/services/llm/exceptions.py +152 -0
- src/services/llm/factory.py +450 -0
- src/services/llm/local_provider.py +347 -0
- src/services/llm/providers/anthropic.py +95 -0
- src/services/llm/providers/base_provider.py +93 -0
- src/services/llm/providers/open_ai.py +83 -0
- src/services/llm/registry.py +71 -0
- src/services/llm/telemetry.py +40 -0
- src/services/llm/types.py +27 -0
- src/services/llm/utils.py +333 -0
- src/services/prompt/__init__.py +25 -0
- src/services/prompt/manager.py +206 -0
- src/services/rag/__init__.py +64 -0
- src/services/rag/components/__init__.py +29 -0
- src/services/rag/components/base.py +59 -0
- src/services/rag/components/chunkers/__init__.py +18 -0
- src/services/rag/components/chunkers/base.py +34 -0
- src/services/rag/components/chunkers/fixed.py +71 -0
- src/services/rag/components/chunkers/numbered_item.py +94 -0
- src/services/rag/components/chunkers/semantic.py +97 -0
- src/services/rag/components/embedders/__init__.py +14 -0
- src/services/rag/components/embedders/base.py +32 -0
- src/services/rag/components/embedders/openai.py +63 -0
- src/services/rag/components/indexers/__init__.py +18 -0
- src/services/rag/components/indexers/base.py +35 -0
- src/services/rag/components/indexers/graph.py +172 -0
- src/services/rag/components/indexers/lightrag.py +156 -0
- src/services/rag/components/indexers/vector.py +146 -0
- src/services/rag/components/parsers/__init__.py +18 -0
- src/services/rag/components/parsers/base.py +35 -0
- src/services/rag/components/parsers/markdown.py +52 -0
- src/services/rag/components/parsers/pdf.py +115 -0
- src/services/rag/components/parsers/text.py +86 -0
- src/services/rag/components/retrievers/__init__.py +18 -0
- src/services/rag/components/retrievers/base.py +34 -0
- src/services/rag/components/retrievers/dense.py +200 -0
- src/services/rag/components/retrievers/hybrid.py +164 -0
- src/services/rag/components/retrievers/lightrag.py +169 -0
- src/services/rag/components/routing.py +286 -0
- src/services/rag/factory.py +234 -0
- src/services/rag/pipeline.py +215 -0
- src/services/rag/pipelines/__init__.py +32 -0
- src/services/rag/pipelines/academic.py +44 -0
- src/services/rag/pipelines/lightrag.py +43 -0
- src/services/rag/pipelines/llamaindex.py +313 -0
- src/services/rag/pipelines/raganything.py +384 -0
- src/services/rag/service.py +244 -0
- src/services/rag/types.py +73 -0
- src/services/search/__init__.py +284 -0
- src/services/search/base.py +87 -0
- src/services/search/consolidation.py +398 -0
- src/services/search/providers/__init__.py +128 -0
- src/services/search/providers/baidu.py +188 -0
- src/services/search/providers/exa.py +194 -0
- src/services/search/providers/jina.py +161 -0
- src/services/search/providers/perplexity.py +153 -0
- src/services/search/providers/serper.py +209 -0
- src/services/search/providers/tavily.py +161 -0
- src/services/search/types.py +114 -0
- src/services/setup/__init__.py +34 -0
- src/services/setup/init.py +285 -0
- src/services/tts/__init__.py +16 -0
- src/services/tts/config.py +99 -0
- src/tools/__init__.py +91 -0
- src/tools/code_executor.py +536 -0
- src/tools/paper_search_tool.py +171 -0
- src/tools/query_item_tool.py +310 -0
- src/tools/question/__init__.py +15 -0
- src/tools/question/exam_mimic.py +616 -0
- src/tools/question/pdf_parser.py +211 -0
- src/tools/question/question_extractor.py +397 -0
- src/tools/rag_tool.py +173 -0
- src/tools/tex_chunker.py +339 -0
- src/tools/tex_downloader.py +253 -0
- src/tools/web_search.py +71 -0
- src/utils/config_manager.py +206 -0
- src/utils/document_validator.py +168 -0
- src/utils/error_rate_tracker.py +111 -0
- src/utils/error_utils.py +82 -0
- src/utils/json_parser.py +110 -0
- src/utils/network/circuit_breaker.py +79 -0
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
"""
|
|
4
|
+
RetrieveAgent - Responsible for generating RAG queries and retrieving knowledge.
|
|
5
|
+
|
|
6
|
+
Uses unified BaseAgent for LLM calls and configuration management.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import asyncio
|
|
10
|
+
import json
|
|
11
|
+
from typing import Any
|
|
12
|
+
|
|
13
|
+
from src.agents.base_agent import BaseAgent
|
|
14
|
+
from src.tools.rag_tool import rag_search
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class RetrieveAgent(BaseAgent):
|
|
18
|
+
"""
|
|
19
|
+
Agent responsible for knowledge retrieval from the knowledge base.
|
|
20
|
+
|
|
21
|
+
Responsibilities:
|
|
22
|
+
- Generate semantic search queries from requirements
|
|
23
|
+
- Execute RAG searches in parallel
|
|
24
|
+
- Merge and summarize retrieval results
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
kb_name: str | None = None,
|
|
30
|
+
rag_mode: str = "naive",
|
|
31
|
+
language: str = "en",
|
|
32
|
+
**kwargs,
|
|
33
|
+
):
|
|
34
|
+
"""
|
|
35
|
+
Initialize RetrieveAgent.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
kb_name: Knowledge base name to search
|
|
39
|
+
rag_mode: RAG search mode ("naive" or "hybrid")
|
|
40
|
+
language: Language for prompts ("en" or "zh")
|
|
41
|
+
**kwargs: Additional arguments passed to BaseAgent
|
|
42
|
+
"""
|
|
43
|
+
super().__init__(
|
|
44
|
+
module_name="question",
|
|
45
|
+
agent_name="retrieve_agent",
|
|
46
|
+
language=language,
|
|
47
|
+
**kwargs,
|
|
48
|
+
)
|
|
49
|
+
self.kb_name = kb_name
|
|
50
|
+
self.rag_mode = rag_mode
|
|
51
|
+
|
|
52
|
+
async def process(
|
|
53
|
+
self,
|
|
54
|
+
requirement: dict[str, Any] | str,
|
|
55
|
+
num_queries: int = 3,
|
|
56
|
+
) -> dict[str, Any]:
|
|
57
|
+
"""
|
|
58
|
+
Main processing: generate queries and retrieve knowledge.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
requirement: Question requirement (dict or string)
|
|
62
|
+
num_queries: Number of RAG queries to generate
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
Dict with:
|
|
66
|
+
- queries: List of generated queries
|
|
67
|
+
- retrievals: List of retrieval results
|
|
68
|
+
- summary: Merged knowledge summary
|
|
69
|
+
"""
|
|
70
|
+
self.logger.info("Starting knowledge retrieval")
|
|
71
|
+
|
|
72
|
+
# Convert requirement to text
|
|
73
|
+
if isinstance(requirement, dict):
|
|
74
|
+
requirement_text = json.dumps(requirement, ensure_ascii=False, indent=2)
|
|
75
|
+
else:
|
|
76
|
+
requirement_text = str(requirement)
|
|
77
|
+
|
|
78
|
+
# Step 1: Generate search queries
|
|
79
|
+
queries = await self._generate_queries(requirement_text, num_queries)
|
|
80
|
+
self.logger.info(f"Generated {len(queries)} search queries")
|
|
81
|
+
|
|
82
|
+
# Step 2: Execute RAG searches in parallel
|
|
83
|
+
retrievals = await self._execute_searches(queries)
|
|
84
|
+
self.logger.info(f"Retrieved {len(retrievals)} results")
|
|
85
|
+
|
|
86
|
+
# Step 3: Summarize results
|
|
87
|
+
summary = self._summarize_retrievals(retrievals)
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
"queries": queries,
|
|
91
|
+
"retrievals": retrievals,
|
|
92
|
+
"summary": summary,
|
|
93
|
+
"has_content": any(r.get("answer", "").strip() for r in retrievals),
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async def _generate_queries(
|
|
97
|
+
self,
|
|
98
|
+
requirement_text: str,
|
|
99
|
+
num_queries: int,
|
|
100
|
+
) -> list[str]:
|
|
101
|
+
"""
|
|
102
|
+
Use LLM to generate semantic search queries from requirement text.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
requirement_text: Natural language requirement
|
|
106
|
+
num_queries: Number of queries to generate
|
|
107
|
+
|
|
108
|
+
Returns:
|
|
109
|
+
List of query strings
|
|
110
|
+
"""
|
|
111
|
+
system_prompt = self.get_prompt("system", "")
|
|
112
|
+
user_prompt_template = self.get_prompt("generate_queries", "")
|
|
113
|
+
|
|
114
|
+
if not user_prompt_template:
|
|
115
|
+
# Fallback prompt
|
|
116
|
+
user_prompt_template = (
|
|
117
|
+
f"Extract {num_queries} knowledge point names from this requirement for retrieval:\n"
|
|
118
|
+
"{requirement_text}\n\n"
|
|
119
|
+
'Return JSON: {{"queries": ["point1", "point2", ...]}}'
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
user_prompt = user_prompt_template.format(
|
|
123
|
+
requirement_text=requirement_text,
|
|
124
|
+
num_queries=num_queries,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
try:
|
|
128
|
+
response = await self.call_llm(
|
|
129
|
+
user_prompt=user_prompt,
|
|
130
|
+
system_prompt=system_prompt,
|
|
131
|
+
response_format={"type": "json_object"},
|
|
132
|
+
stage="generate_queries",
|
|
133
|
+
)
|
|
134
|
+
|
|
135
|
+
data = json.loads(response)
|
|
136
|
+
queries_raw = data.get("queries", [])
|
|
137
|
+
|
|
138
|
+
# Ensure queries is a list
|
|
139
|
+
if not isinstance(queries_raw, list):
|
|
140
|
+
if isinstance(queries_raw, dict):
|
|
141
|
+
queries_raw = list(queries_raw.values())
|
|
142
|
+
elif isinstance(queries_raw, str):
|
|
143
|
+
queries_raw = [queries_raw]
|
|
144
|
+
else:
|
|
145
|
+
queries_raw = []
|
|
146
|
+
|
|
147
|
+
queries = [q.strip() for q in queries_raw if q and q.strip()]
|
|
148
|
+
|
|
149
|
+
except Exception as e:
|
|
150
|
+
self.logger.warning(f"Failed to generate queries: {e}")
|
|
151
|
+
queries = []
|
|
152
|
+
|
|
153
|
+
# Fallback: use requirement text as query
|
|
154
|
+
if not queries:
|
|
155
|
+
queries = [requirement_text[:100]]
|
|
156
|
+
|
|
157
|
+
return queries[:num_queries]
|
|
158
|
+
|
|
159
|
+
async def _single_rag_search(self, query: str) -> dict[str, Any]:
|
|
160
|
+
"""
|
|
161
|
+
Execute a single RAG search.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
query: Search query
|
|
165
|
+
|
|
166
|
+
Returns:
|
|
167
|
+
Dict with query and answer
|
|
168
|
+
"""
|
|
169
|
+
try:
|
|
170
|
+
result = await rag_search(
|
|
171
|
+
query=query,
|
|
172
|
+
kb_name=self.kb_name,
|
|
173
|
+
mode=self.rag_mode,
|
|
174
|
+
only_need_context=True,
|
|
175
|
+
)
|
|
176
|
+
return {
|
|
177
|
+
"query": query,
|
|
178
|
+
"answer": result.get("answer", ""),
|
|
179
|
+
"mode": result.get("mode", self.rag_mode),
|
|
180
|
+
}
|
|
181
|
+
except Exception as e:
|
|
182
|
+
self.logger.warning(f"RAG search failed for '{query}': {e}")
|
|
183
|
+
return {
|
|
184
|
+
"query": query,
|
|
185
|
+
"answer": "",
|
|
186
|
+
"error": str(e),
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async def _execute_searches(self, queries: list[str]) -> list[dict[str, Any]]:
|
|
190
|
+
"""
|
|
191
|
+
Execute RAG searches in parallel.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
queries: List of search queries
|
|
195
|
+
|
|
196
|
+
Returns:
|
|
197
|
+
List of retrieval results
|
|
198
|
+
"""
|
|
199
|
+
self.logger.debug(f"Executing {len(queries)} RAG searches in parallel")
|
|
200
|
+
|
|
201
|
+
tasks = [self._single_rag_search(query) for query in queries]
|
|
202
|
+
results = await asyncio.gather(*tasks, return_exceptions=True)
|
|
203
|
+
|
|
204
|
+
retrievals = []
|
|
205
|
+
for i, result in enumerate(results):
|
|
206
|
+
if isinstance(result, Exception):
|
|
207
|
+
self.logger.warning(f"Search failed for query '{queries[i]}': {result}")
|
|
208
|
+
continue
|
|
209
|
+
if result.get("answer"):
|
|
210
|
+
retrievals.append(result)
|
|
211
|
+
self.logger.debug(f" → Query: {queries[i][:50]}... (retrieved)")
|
|
212
|
+
|
|
213
|
+
return retrievals
|
|
214
|
+
|
|
215
|
+
def _summarize_retrievals(self, retrievals: list[dict[str, Any]]) -> str:
|
|
216
|
+
"""
|
|
217
|
+
Merge retrieval results into a summary string.
|
|
218
|
+
|
|
219
|
+
Args:
|
|
220
|
+
retrievals: List of retrieval results
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
Merged summary string
|
|
224
|
+
"""
|
|
225
|
+
if not retrievals:
|
|
226
|
+
return "No retrieval context available."
|
|
227
|
+
|
|
228
|
+
lines = []
|
|
229
|
+
for item in retrievals:
|
|
230
|
+
lines.append(f"=== Query: {item['query']} ===")
|
|
231
|
+
answer = item.get("answer", "")
|
|
232
|
+
if answer:
|
|
233
|
+
# Truncate very long answers
|
|
234
|
+
if len(answer) > 2000:
|
|
235
|
+
answer = answer[:2000] + "...[truncated]"
|
|
236
|
+
lines.append(answer)
|
|
237
|
+
lines.append("")
|
|
238
|
+
|
|
239
|
+
return "\n".join(lines)
|