jarvis-ai-assistant 0.1.138__py3-none-any.whl → 0.1.141__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.
Potentially problematic release.
This version of jarvis-ai-assistant might be problematic. Click here for more details.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +62 -14
- jarvis/jarvis_agent/builtin_input_handler.py +4 -14
- jarvis/jarvis_agent/main.py +1 -1
- jarvis/jarvis_agent/patch.py +37 -40
- jarvis/jarvis_agent/shell_input_handler.py +2 -3
- jarvis/jarvis_code_agent/code_agent.py +23 -30
- jarvis/jarvis_code_analysis/checklists/__init__.py +3 -0
- jarvis/jarvis_code_analysis/checklists/c_cpp.py +50 -0
- jarvis/jarvis_code_analysis/checklists/csharp.py +75 -0
- jarvis/jarvis_code_analysis/checklists/data_format.py +82 -0
- jarvis/jarvis_code_analysis/checklists/devops.py +107 -0
- jarvis/jarvis_code_analysis/checklists/docs.py +87 -0
- jarvis/jarvis_code_analysis/checklists/go.py +52 -0
- jarvis/jarvis_code_analysis/checklists/infrastructure.py +98 -0
- jarvis/jarvis_code_analysis/checklists/java.py +66 -0
- jarvis/jarvis_code_analysis/checklists/javascript.py +73 -0
- jarvis/jarvis_code_analysis/checklists/kotlin.py +107 -0
- jarvis/jarvis_code_analysis/checklists/loader.py +76 -0
- jarvis/jarvis_code_analysis/checklists/php.py +77 -0
- jarvis/jarvis_code_analysis/checklists/python.py +56 -0
- jarvis/jarvis_code_analysis/checklists/ruby.py +107 -0
- jarvis/jarvis_code_analysis/checklists/rust.py +58 -0
- jarvis/jarvis_code_analysis/checklists/shell.py +75 -0
- jarvis/jarvis_code_analysis/checklists/sql.py +72 -0
- jarvis/jarvis_code_analysis/checklists/swift.py +77 -0
- jarvis/jarvis_code_analysis/checklists/web.py +97 -0
- jarvis/jarvis_code_analysis/code_review.py +660 -0
- jarvis/jarvis_dev/main.py +61 -88
- jarvis/jarvis_git_squash/main.py +3 -3
- jarvis/jarvis_git_utils/git_commiter.py +242 -0
- jarvis/jarvis_init/main.py +62 -0
- jarvis/jarvis_platform/base.py +4 -0
- jarvis/jarvis_platform/kimi.py +173 -5
- jarvis/jarvis_platform/openai.py +3 -0
- jarvis/jarvis_platform/registry.py +1 -0
- jarvis/jarvis_platform/yuanbao.py +275 -5
- jarvis/jarvis_tools/ask_codebase.py +6 -9
- jarvis/jarvis_tools/ask_user.py +17 -5
- jarvis/jarvis_tools/base.py +3 -1
- jarvis/jarvis_tools/chdir.py +1 -0
- jarvis/jarvis_tools/create_code_agent.py +4 -3
- jarvis/jarvis_tools/create_sub_agent.py +1 -0
- jarvis/jarvis_tools/execute_script.py +170 -0
- jarvis/jarvis_tools/file_analyzer.py +90 -239
- jarvis/jarvis_tools/file_operation.py +99 -31
- jarvis/jarvis_tools/{find_methodolopy.py → find_methodology.py} +2 -1
- jarvis/jarvis_tools/lsp_get_diagnostics.py +2 -0
- jarvis/jarvis_tools/methodology.py +11 -11
- jarvis/jarvis_tools/read_code.py +2 -0
- jarvis/jarvis_tools/read_webpage.py +33 -196
- jarvis/jarvis_tools/registry.py +68 -131
- jarvis/jarvis_tools/search_web.py +14 -6
- jarvis/jarvis_tools/virtual_tty.py +399 -0
- jarvis/jarvis_utils/config.py +29 -3
- jarvis/jarvis_utils/embedding.py +0 -317
- jarvis/jarvis_utils/file_processors.py +343 -0
- jarvis/jarvis_utils/input.py +0 -1
- jarvis/jarvis_utils/methodology.py +94 -435
- jarvis/jarvis_utils/utils.py +207 -9
- {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/METADATA +4 -4
- jarvis_ai_assistant-0.1.141.dist-info/RECORD +94 -0
- {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/entry_points.txt +4 -4
- jarvis/jarvis_code_agent/file_select.py +0 -202
- jarvis/jarvis_platform/ai8.py +0 -268
- jarvis/jarvis_platform/ollama.py +0 -137
- jarvis/jarvis_platform/oyi.py +0 -307
- jarvis/jarvis_rag/file_processors.py +0 -138
- jarvis/jarvis_rag/main.py +0 -1734
- jarvis/jarvis_tools/code_review.py +0 -333
- jarvis/jarvis_tools/execute_python_script.py +0 -58
- jarvis/jarvis_tools/execute_shell.py +0 -97
- jarvis/jarvis_tools/execute_shell_script.py +0 -58
- jarvis/jarvis_tools/find_caller.py +0 -278
- jarvis/jarvis_tools/find_symbol.py +0 -295
- jarvis/jarvis_tools/function_analyzer.py +0 -331
- jarvis/jarvis_tools/git_commiter.py +0 -167
- jarvis/jarvis_tools/project_analyzer.py +0 -304
- jarvis/jarvis_tools/rag.py +0 -143
- jarvis/jarvis_tools/tool_generator.py +0 -221
- jarvis_ai_assistant-0.1.138.dist-info/RECORD +0 -85
- /jarvis/{jarvis_rag → jarvis_init}/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.138.dist-info → jarvis_ai_assistant-0.1.141.dist-info}/top_level.txt +0 -0
|
@@ -2,224 +2,17 @@
|
|
|
2
2
|
方法论管理模块
|
|
3
3
|
该模块提供了加载和搜索方法论的实用工具。
|
|
4
4
|
包含以下功能:
|
|
5
|
-
- 创建方法论嵌入向量
|
|
6
5
|
- 加载和处理方法论数据
|
|
7
|
-
-
|
|
8
|
-
-
|
|
6
|
+
- 生成方法论临时文件
|
|
7
|
+
- 上传方法论文件到大模型
|
|
9
8
|
"""
|
|
10
9
|
import os
|
|
11
|
-
import yaml
|
|
12
|
-
import glob
|
|
13
10
|
import json
|
|
14
11
|
import hashlib
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import faiss
|
|
18
|
-
from typing import Dict, Any, List, Tuple, Optional
|
|
12
|
+
import tempfile
|
|
13
|
+
from typing import Dict, List, Optional
|
|
19
14
|
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
20
|
-
from jarvis.
|
|
21
|
-
|
|
22
|
-
# 全局缓存,避免重复计算嵌入向量
|
|
23
|
-
_methodology_embeddings_cache = {}
|
|
24
|
-
_methodology_index_cache: Optional[Tuple[faiss.IndexIDMap, List[Dict[str, str]], str]] = None
|
|
25
|
-
|
|
26
|
-
def _get_cache_directory() -> str:
|
|
27
|
-
"""
|
|
28
|
-
获取缓存目录路径,如果不存在则创建
|
|
29
|
-
|
|
30
|
-
返回:
|
|
31
|
-
str: 缓存目录的路径
|
|
32
|
-
"""
|
|
33
|
-
cache_dir = os.path.expanduser("~/.jarvis/cache")
|
|
34
|
-
if not os.path.exists(cache_dir):
|
|
35
|
-
try:
|
|
36
|
-
os.makedirs(cache_dir, exist_ok=True)
|
|
37
|
-
except Exception as e:
|
|
38
|
-
PrettyOutput.print(f"创建缓存目录失败: {str(e)}", OutputType.ERROR)
|
|
39
|
-
return cache_dir
|
|
40
|
-
|
|
41
|
-
def _get_embeddings_cache_path() -> str:
|
|
42
|
-
"""
|
|
43
|
-
获取嵌入向量缓存文件的路径
|
|
44
|
-
|
|
45
|
-
返回:
|
|
46
|
-
str: 嵌入向量缓存文件的路径
|
|
47
|
-
"""
|
|
48
|
-
return os.path.join(_get_cache_directory(), "methodology_embeddings.pkl")
|
|
49
|
-
|
|
50
|
-
def _get_index_cache_path() -> str:
|
|
51
|
-
"""
|
|
52
|
-
获取索引缓存文件的路径
|
|
53
|
-
|
|
54
|
-
返回:
|
|
55
|
-
str: 索引缓存文件的路径
|
|
56
|
-
"""
|
|
57
|
-
return os.path.join(_get_cache_directory(), "methodology_index.faiss")
|
|
58
|
-
|
|
59
|
-
def _get_index_metadata_path() -> str:
|
|
60
|
-
"""
|
|
61
|
-
获取索引元数据文件的路径
|
|
62
|
-
|
|
63
|
-
返回:
|
|
64
|
-
str: 索引元数据文件的路径
|
|
65
|
-
"""
|
|
66
|
-
return os.path.join(_get_cache_directory(), "methodology_index_metadata.pkl")
|
|
67
|
-
|
|
68
|
-
def _load_embeddings_cache() -> Dict[int, np.ndarray]:
|
|
69
|
-
"""
|
|
70
|
-
从文件系统加载嵌入向量缓存
|
|
71
|
-
|
|
72
|
-
返回:
|
|
73
|
-
Dict[int, np.ndarray]: 嵌入向量缓存字典
|
|
74
|
-
"""
|
|
75
|
-
cache_path = _get_embeddings_cache_path()
|
|
76
|
-
if not os.path.exists(cache_path):
|
|
77
|
-
return {}
|
|
78
|
-
|
|
79
|
-
try:
|
|
80
|
-
with open(cache_path, "rb") as f:
|
|
81
|
-
embeddings_cache = pickle.load(f)
|
|
82
|
-
return embeddings_cache
|
|
83
|
-
except Exception as e:
|
|
84
|
-
return {}
|
|
85
|
-
|
|
86
|
-
def _save_embeddings_cache(cache: Dict[int, np.ndarray]) -> bool:
|
|
87
|
-
"""
|
|
88
|
-
将嵌入向量缓存保存到文件系统
|
|
89
|
-
|
|
90
|
-
参数:
|
|
91
|
-
cache: 要保存的嵌入向量缓存字典
|
|
92
|
-
|
|
93
|
-
返回:
|
|
94
|
-
bool: 保存是否成功
|
|
95
|
-
"""
|
|
96
|
-
if not cache:
|
|
97
|
-
return False
|
|
98
|
-
|
|
99
|
-
cache_path = _get_embeddings_cache_path()
|
|
100
|
-
|
|
101
|
-
try:
|
|
102
|
-
with open(cache_path, "wb") as f:
|
|
103
|
-
pickle.dump(cache, f)
|
|
104
|
-
return True
|
|
105
|
-
except Exception as e:
|
|
106
|
-
PrettyOutput.print(f"保存嵌入向量缓存失败: {str(e)}", OutputType.WARNING)
|
|
107
|
-
return False
|
|
108
|
-
|
|
109
|
-
def _load_index_cache() -> Optional[Tuple[faiss.IndexIDMap, List[Dict[str, str]], str]]:
|
|
110
|
-
"""
|
|
111
|
-
从文件系统加载索引缓存
|
|
112
|
-
|
|
113
|
-
返回:
|
|
114
|
-
Optional[Tuple[faiss.IndexIDMap, List[Dict[str, str]], str]]: 索引缓存元组
|
|
115
|
-
"""
|
|
116
|
-
index_path = _get_index_cache_path()
|
|
117
|
-
metadata_path = _get_index_metadata_path()
|
|
118
|
-
|
|
119
|
-
if not os.path.exists(index_path) or not os.path.exists(metadata_path):
|
|
120
|
-
return None
|
|
121
|
-
|
|
122
|
-
try:
|
|
123
|
-
# 加载索引
|
|
124
|
-
index = faiss.read_index(index_path)
|
|
125
|
-
|
|
126
|
-
# 加载元数据
|
|
127
|
-
with open(metadata_path, "rb") as f:
|
|
128
|
-
metadata = pickle.load(f)
|
|
129
|
-
|
|
130
|
-
methodology_data = metadata.get("methodology_data", [])
|
|
131
|
-
methodology_hash = metadata.get("methodology_hash", "")
|
|
132
|
-
|
|
133
|
-
if isinstance(index, faiss.IndexIDMap) and methodology_data and methodology_hash:
|
|
134
|
-
return index, methodology_data, methodology_hash
|
|
135
|
-
except Exception as e:
|
|
136
|
-
PrettyOutput.print(f"加载索引缓存失败: {str(e)}", OutputType.WARNING)
|
|
137
|
-
|
|
138
|
-
return None
|
|
139
|
-
|
|
140
|
-
def _save_index_cache(index: faiss.IndexIDMap, methodology_data: List[Dict[str, str]], methodology_hash: str) -> bool:
|
|
141
|
-
"""
|
|
142
|
-
将索引缓存保存到文件系统
|
|
143
|
-
|
|
144
|
-
参数:
|
|
145
|
-
index: FAISS索引
|
|
146
|
-
methodology_data: 方法论数据列表
|
|
147
|
-
methodology_hash: 方法论文件哈希值
|
|
148
|
-
|
|
149
|
-
返回:
|
|
150
|
-
bool: 保存是否成功
|
|
151
|
-
"""
|
|
152
|
-
index_path = _get_index_cache_path()
|
|
153
|
-
metadata_path = _get_index_metadata_path()
|
|
154
|
-
|
|
155
|
-
try:
|
|
156
|
-
# 保存索引
|
|
157
|
-
faiss.write_index(index, index_path)
|
|
158
|
-
|
|
159
|
-
# 保存元数据
|
|
160
|
-
metadata = {
|
|
161
|
-
"methodology_data": methodology_data,
|
|
162
|
-
"methodology_hash": methodology_hash
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
with open(metadata_path, "wb") as f:
|
|
166
|
-
pickle.dump(metadata, f)
|
|
167
|
-
|
|
168
|
-
return True
|
|
169
|
-
except Exception as e:
|
|
170
|
-
PrettyOutput.print(f"保存索引缓存失败: {str(e)}", OutputType.WARNING)
|
|
171
|
-
return False
|
|
172
|
-
|
|
173
|
-
def _create_methodology_embedding(embedding_model: Any, methodology_text: str) -> np.ndarray:
|
|
174
|
-
"""
|
|
175
|
-
为方法论文本创建嵌入向量。
|
|
176
|
-
|
|
177
|
-
参数:
|
|
178
|
-
embedding_model: 使用的嵌入模型
|
|
179
|
-
methodology_text: 要创建嵌入的文本
|
|
180
|
-
|
|
181
|
-
返回:
|
|
182
|
-
np.ndarray: 嵌入向量
|
|
183
|
-
"""
|
|
184
|
-
try:
|
|
185
|
-
# 检查缓存中是否已有此文本的嵌入向量
|
|
186
|
-
cache_key = hash(methodology_text)
|
|
187
|
-
if cache_key in _methodology_embeddings_cache:
|
|
188
|
-
return _methodology_embeddings_cache[cache_key]
|
|
189
|
-
|
|
190
|
-
# 截断长文本
|
|
191
|
-
max_length = 512
|
|
192
|
-
text = ' '.join(methodology_text.split()[:max_length])
|
|
193
|
-
|
|
194
|
-
# 使用sentence_transformers模型获取嵌入向量
|
|
195
|
-
embedding = embedding_model.encode([text],
|
|
196
|
-
convert_to_tensor=True,
|
|
197
|
-
normalize_embeddings=True)
|
|
198
|
-
vector = np.array(embedding.cpu().numpy(), dtype=np.float32)
|
|
199
|
-
result = vector[0] # 返回第一个向量,因为我们只编码了一个文本
|
|
200
|
-
|
|
201
|
-
# 缓存嵌入向量以便后续使用
|
|
202
|
-
_methodology_embeddings_cache[cache_key] = result
|
|
203
|
-
|
|
204
|
-
return result
|
|
205
|
-
except Exception as e:
|
|
206
|
-
PrettyOutput.print(f"创建方法论嵌入向量失败: {str(e)}", OutputType.ERROR)
|
|
207
|
-
return np.zeros(1536, dtype=np.float32)
|
|
208
|
-
|
|
209
|
-
def make_methodology_prompt(data: Dict[str, str]) -> str:
|
|
210
|
-
"""
|
|
211
|
-
从方法论数据生成格式化提示
|
|
212
|
-
|
|
213
|
-
参数:
|
|
214
|
-
data: 方法论数据字典
|
|
215
|
-
|
|
216
|
-
返回:
|
|
217
|
-
str: 格式化后的提示字符串
|
|
218
|
-
"""
|
|
219
|
-
ret = """这是处理以往问题的标准方法论,如果当前任务类似,可以参考使用,如果不相关,请忽略:\n"""
|
|
220
|
-
for key, value in data.items():
|
|
221
|
-
ret += f"问题: {key}\n方法论: {value}\n"
|
|
222
|
-
return ret
|
|
15
|
+
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
223
16
|
|
|
224
17
|
def _get_methodology_directory() -> str:
|
|
225
18
|
"""
|
|
@@ -236,36 +29,6 @@ def _get_methodology_directory() -> str:
|
|
|
236
29
|
PrettyOutput.print(f"创建方法论目录失败: {str(e)}", OutputType.ERROR)
|
|
237
30
|
return methodology_dir
|
|
238
31
|
|
|
239
|
-
def _get_methodology_files_hash() -> str:
|
|
240
|
-
"""
|
|
241
|
-
计算所有方法论文件的组合哈希值,用于检测文件变化
|
|
242
|
-
|
|
243
|
-
返回:
|
|
244
|
-
str: 所有方法论文件的组合哈希值
|
|
245
|
-
"""
|
|
246
|
-
methodology_dir = _get_methodology_directory()
|
|
247
|
-
if not os.path.exists(methodology_dir):
|
|
248
|
-
return ""
|
|
249
|
-
|
|
250
|
-
# 获取所有方法论文件的路径和修改时间
|
|
251
|
-
files_data = []
|
|
252
|
-
for filepath in glob.glob(os.path.join(methodology_dir, "*.json")):
|
|
253
|
-
mtime = os.path.getmtime(filepath)
|
|
254
|
-
files_data.append((filepath, mtime))
|
|
255
|
-
|
|
256
|
-
# 按路径排序,保证哈希值的一致性
|
|
257
|
-
files_data.sort(key=lambda x: x[0])
|
|
258
|
-
|
|
259
|
-
# 计算组合哈希值
|
|
260
|
-
if not files_data:
|
|
261
|
-
return ""
|
|
262
|
-
|
|
263
|
-
hasher = hashlib.md5()
|
|
264
|
-
for filepath, mtime in files_data:
|
|
265
|
-
hasher.update(f"{filepath}:{mtime}".encode("utf-8"))
|
|
266
|
-
|
|
267
|
-
return hasher.hexdigest()
|
|
268
|
-
|
|
269
32
|
def _load_all_methodologies() -> Dict[str, str]:
|
|
270
33
|
"""
|
|
271
34
|
加载所有方法论文件
|
|
@@ -279,6 +42,7 @@ def _load_all_methodologies() -> Dict[str, str]:
|
|
|
279
42
|
if not os.path.exists(methodology_dir):
|
|
280
43
|
return all_methodologies
|
|
281
44
|
|
|
45
|
+
import glob
|
|
282
46
|
for filepath in glob.glob(os.path.join(methodology_dir, "*.json")):
|
|
283
47
|
try:
|
|
284
48
|
with open(filepath, "r", encoding="utf-8", errors="ignore") as f:
|
|
@@ -293,227 +57,122 @@ def _load_all_methodologies() -> Dict[str, str]:
|
|
|
293
57
|
|
|
294
58
|
return all_methodologies
|
|
295
59
|
|
|
296
|
-
def
|
|
60
|
+
def _create_methodology_temp_file(methodologies: Dict[str, str]) -> Optional[str]:
|
|
297
61
|
"""
|
|
298
|
-
|
|
299
|
-
"""
|
|
300
|
-
old_format_file = os.path.expanduser("~/.jarvis/methodology")
|
|
301
|
-
if not os.path.exists(old_format_file):
|
|
302
|
-
return
|
|
303
|
-
|
|
304
|
-
try:
|
|
305
|
-
# 加载旧格式文件
|
|
306
|
-
with open(old_format_file, "r", encoding="utf-8", errors="ignore") as f:
|
|
307
|
-
old_data = yaml.safe_load(f) or {}
|
|
308
|
-
|
|
309
|
-
if not old_data:
|
|
310
|
-
return
|
|
311
|
-
|
|
312
|
-
# 创建新目录
|
|
313
|
-
methodology_dir = _get_methodology_directory()
|
|
314
|
-
|
|
315
|
-
# 迁移每个方法论
|
|
316
|
-
migrated_count = 0
|
|
317
|
-
for problem_type, content in old_data.items():
|
|
318
|
-
# 为每个方法论创建文件名(使用问题类型的MD5哈希作为文件名)
|
|
319
|
-
safe_filename = hashlib.md5(problem_type.encode('utf-8')).hexdigest()
|
|
320
|
-
file_path = os.path.join(methodology_dir, f"{safe_filename}.json")
|
|
62
|
+
创建包含所有方法论的临时文件
|
|
321
63
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
json.dump({
|
|
325
|
-
"problem_type": problem_type,
|
|
326
|
-
"content": content
|
|
327
|
-
}, f, ensure_ascii=False, indent=2)
|
|
328
|
-
|
|
329
|
-
migrated_count += 1
|
|
64
|
+
参数:
|
|
65
|
+
methodologies: 方法论字典,键为问题类型,值为方法论内容
|
|
330
66
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
67
|
+
返回:
|
|
68
|
+
Optional[str]: 临时文件路径,如果创建失败则返回None
|
|
69
|
+
"""
|
|
70
|
+
if not methodologies:
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
try:
|
|
74
|
+
# 创建临时文件
|
|
75
|
+
fd, temp_path = tempfile.mkstemp(suffix='.md', prefix='methodologies_')
|
|
76
|
+
os.close(fd)
|
|
77
|
+
|
|
78
|
+
# 写入方法论内容
|
|
79
|
+
with open(temp_path, 'w', encoding='utf-8') as f:
|
|
80
|
+
f.write("# 方法论集合\n\n")
|
|
81
|
+
for problem_type, content in methodologies.items():
|
|
82
|
+
f.write(f"## {problem_type}\n\n")
|
|
83
|
+
f.write(f"{content}\n\n")
|
|
84
|
+
f.write("---\n\n")
|
|
85
|
+
|
|
86
|
+
return temp_path
|
|
339
87
|
except Exception as e:
|
|
340
|
-
PrettyOutput.print(f"
|
|
88
|
+
PrettyOutput.print(f"创建方法论临时文件失败: {str(e)}", OutputType.ERROR)
|
|
89
|
+
return None
|
|
341
90
|
|
|
342
91
|
def load_methodology(user_input: str) -> str:
|
|
343
92
|
"""
|
|
344
|
-
|
|
93
|
+
加载方法论并上传到大模型。
|
|
345
94
|
|
|
346
95
|
参数:
|
|
347
|
-
user_input:
|
|
96
|
+
user_input: 用户输入文本,用于提示大模型
|
|
348
97
|
|
|
349
98
|
返回:
|
|
350
99
|
str: 相关的方法论提示,如果未找到方法论则返回空字符串
|
|
351
100
|
"""
|
|
352
101
|
from yaspin import yaspin
|
|
353
102
|
|
|
354
|
-
# 加载嵌入向量缓存
|
|
355
|
-
global _methodology_embeddings_cache
|
|
356
|
-
if not _methodology_embeddings_cache:
|
|
357
|
-
with yaspin(text="加载嵌入向量缓存...", color="yellow") as spinner:
|
|
358
|
-
_methodology_embeddings_cache = _load_embeddings_cache()
|
|
359
|
-
spinner.text = f"加载嵌入向量缓存完成 ({len(_methodology_embeddings_cache)} 个向量)"
|
|
360
|
-
spinner.ok("✅")
|
|
361
|
-
|
|
362
|
-
# 检查是否需要从旧格式迁移
|
|
363
|
-
with yaspin(text="检查方法论格式...", color="yellow") as spinner:
|
|
364
|
-
_migrate_from_old_format()
|
|
365
|
-
spinner.text = "检查方法论格式完成"
|
|
366
|
-
spinner.ok("✅")
|
|
367
|
-
|
|
368
103
|
# 获取方法论目录
|
|
369
104
|
methodology_dir = _get_methodology_directory()
|
|
370
|
-
if not os.path.exists(methodology_dir)
|
|
105
|
+
if not os.path.exists(methodology_dir):
|
|
371
106
|
return ""
|
|
372
107
|
|
|
373
108
|
try:
|
|
374
|
-
#
|
|
375
|
-
methodology_hash = _get_methodology_files_hash()
|
|
376
|
-
|
|
377
|
-
# 检查缓存的索引是否可用且方法论文件未被修改
|
|
378
|
-
global _methodology_index_cache
|
|
379
|
-
if _methodology_index_cache is None:
|
|
380
|
-
# 尝试从文件系统加载索引缓存
|
|
381
|
-
with yaspin(text="加载索引缓存...", color="yellow") as spinner:
|
|
382
|
-
_methodology_index_cache = _load_index_cache()
|
|
383
|
-
if _methodology_index_cache:
|
|
384
|
-
spinner.text = "加载索引缓存完成"
|
|
385
|
-
spinner.ok("✅")
|
|
386
|
-
else:
|
|
387
|
-
spinner.text = "没有可用的索引缓存"
|
|
388
|
-
spinner.fail("❌")
|
|
389
|
-
|
|
390
|
-
if _methodology_index_cache is not None:
|
|
391
|
-
cached_index, cached_data, cache_hash = _methodology_index_cache
|
|
392
|
-
if cache_hash == methodology_hash:
|
|
393
|
-
# 直接使用缓存的索引和数据
|
|
394
|
-
with yaspin(text="使用缓存的方法论索引...", color="yellow") as spinner:
|
|
395
|
-
methodology_index = cached_index
|
|
396
|
-
methodology_data = cached_data
|
|
397
|
-
spinner.text = "使用缓存的方法论索引完成"
|
|
398
|
-
spinner.ok("✅")
|
|
399
|
-
|
|
400
|
-
with yaspin(text="加载嵌入模型...", color="yellow") as spinner:
|
|
401
|
-
embedding_model = load_embedding_model()
|
|
402
|
-
spinner.text = "加载嵌入模型完成"
|
|
403
|
-
spinner.ok("✅")
|
|
404
|
-
|
|
405
|
-
with yaspin(text="执行搜索...", color="yellow") as spinner:
|
|
406
|
-
# 使用缓存构造输入文本的嵌入
|
|
407
|
-
query_embedding = _create_methodology_embedding(embedding_model, user_input)
|
|
408
|
-
k = min(3, len(methodology_data))
|
|
409
|
-
distances, indices = methodology_index.search(
|
|
410
|
-
query_embedding.reshape(1, -1), k
|
|
411
|
-
) # type: ignore
|
|
412
|
-
spinner.text = "执行搜索完成"
|
|
413
|
-
spinner.ok("✅")
|
|
414
|
-
|
|
415
|
-
with yaspin(text="处理搜索结果...", color="yellow") as spinner:
|
|
416
|
-
relevant_methodologies = {}
|
|
417
|
-
for dist, idx in zip(distances[0], indices[0]):
|
|
418
|
-
if idx >= 0:
|
|
419
|
-
similarity = 1.0 / (1.0 + float(dist))
|
|
420
|
-
methodology = methodology_data[idx]
|
|
421
|
-
if similarity >= 0.5:
|
|
422
|
-
relevant_methodologies[methodology["key"]] = methodology["value"]
|
|
423
|
-
spinner.text = "处理搜索结果完成"
|
|
424
|
-
spinner.ok("✅")
|
|
425
|
-
|
|
426
|
-
if relevant_methodologies:
|
|
427
|
-
spinner.text = f"找到相关方法论: {', '.join(relevant_methodologies.keys())}"
|
|
428
|
-
spinner.ok("✅")
|
|
429
|
-
return make_methodology_prompt(relevant_methodologies)
|
|
430
|
-
|
|
431
|
-
# 如果缓存无效,从头构建索引
|
|
432
|
-
with yaspin(text="初始化数据结构...", color="yellow") as spinner:
|
|
433
|
-
methodology_data: List[Dict[str, str]] = []
|
|
434
|
-
vectors: List[np.ndarray] = []
|
|
435
|
-
ids: List[int] = []
|
|
436
|
-
spinner.text = "初始化数据结构完成"
|
|
437
|
-
spinner.ok("✅")
|
|
438
|
-
|
|
439
|
-
with yaspin(text="加载嵌入模型...", color="yellow") as spinner:
|
|
440
|
-
embedding_model = load_embedding_model()
|
|
441
|
-
spinner.text = "加载嵌入模型完成"
|
|
442
|
-
spinner.ok("✅")
|
|
443
|
-
|
|
444
|
-
with yaspin(text="创建测试嵌入...", color="yellow") as spinner:
|
|
445
|
-
test_embedding = _create_methodology_embedding(embedding_model, "test")
|
|
446
|
-
embedding_dimension = len(test_embedding)
|
|
447
|
-
spinner.text = "创建测试嵌入完成"
|
|
448
|
-
spinner.ok("✅")
|
|
449
|
-
|
|
109
|
+
# 加载所有方法论
|
|
450
110
|
with yaspin(text="加载方法论文件...", color="yellow") as spinner:
|
|
451
|
-
|
|
452
|
-
|
|
111
|
+
methodologies = _load_all_methodologies()
|
|
112
|
+
if not methodologies:
|
|
113
|
+
spinner.text = "没有找到方法论文件"
|
|
114
|
+
spinner.fail("❌")
|
|
115
|
+
return ""
|
|
116
|
+
spinner.text = f"加载方法论文件完成 (共 {len(methodologies)} 个)"
|
|
453
117
|
spinner.ok("✅")
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
spinner.text = "
|
|
118
|
+
|
|
119
|
+
# 创建临时文件
|
|
120
|
+
with yaspin(text="创建方法论临时文件...", color="yellow") as spinner:
|
|
121
|
+
temp_file_path = _create_methodology_temp_file(methodologies)
|
|
122
|
+
if not temp_file_path:
|
|
123
|
+
spinner.text = "创建方法论临时文件失败"
|
|
124
|
+
spinner.fail("❌")
|
|
125
|
+
return ""
|
|
126
|
+
spinner.text = f"创建方法论临时文件完成: {temp_file_path}"
|
|
463
127
|
spinner.ok("✅")
|
|
464
128
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
129
|
+
# 获取当前平台
|
|
130
|
+
platform = PlatformRegistry().get_thinking_platform()
|
|
131
|
+
|
|
132
|
+
# 上传文件到大模型
|
|
133
|
+
with yaspin(text="上传方法论文件到大模型...", color="yellow") as spinner:
|
|
134
|
+
with spinner.hidden():
|
|
135
|
+
# 上传文件
|
|
136
|
+
upload_result = platform.upload_files([temp_file_path])
|
|
137
|
+
if not upload_result:
|
|
138
|
+
spinner.text = "上传方法论文件失败"
|
|
139
|
+
spinner.fail("❌")
|
|
140
|
+
return ""
|
|
141
|
+
|
|
142
|
+
spinner.text = "上传方法论文件成功"
|
|
143
|
+
spinner.ok("✅")
|
|
144
|
+
|
|
145
|
+
# 构建提示信息
|
|
146
|
+
prompt = f"""根据用户需求: {user_input}
|
|
481
147
|
|
|
482
|
-
|
|
483
|
-
query_embedding = _create_methodology_embedding(embedding_model, user_input)
|
|
484
|
-
k = min(10, len(methodology_data))
|
|
485
|
-
distances, indices = methodology_index.search(
|
|
486
|
-
query_embedding.reshape(1, -1), k
|
|
487
|
-
) # type: ignore
|
|
488
|
-
spinner.text = "执行搜索完成"
|
|
489
|
-
spinner.ok("✅")
|
|
148
|
+
请按以下格式回复:
|
|
490
149
|
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
if idx >= 0:
|
|
495
|
-
similarity = 1.0 / (1.0 + float(dist))
|
|
496
|
-
methodology = methodology_data[idx]
|
|
497
|
-
if similarity >= 0.5:
|
|
498
|
-
relevant_methodologies[methodology["key"]] = methodology["value"]
|
|
499
|
-
spinner.text = "处理搜索结果完成"
|
|
500
|
-
spinner.ok("✅")
|
|
150
|
+
### 方法论步骤
|
|
151
|
+
1. [步骤1描述]
|
|
152
|
+
2. [步骤2描述]
|
|
501
153
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
if _save_embeddings_cache(_methodology_embeddings_cache):
|
|
505
|
-
spinner.text = f"保存嵌入向量缓存完成 ({len(_methodology_embeddings_cache)} 个向量)"
|
|
506
|
-
spinner.ok("✅")
|
|
507
|
-
else:
|
|
508
|
-
spinner.text = "保存嵌入向量缓存失败"
|
|
509
|
-
spinner.fail("❌")
|
|
154
|
+
如果没有匹配的方法论,请提供执行计划并注明:
|
|
155
|
+
(未参考任何现有方法论)
|
|
510
156
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
157
|
+
### 执行计划
|
|
158
|
+
1. [步骤1描述]
|
|
159
|
+
2. [步骤2描述]
|
|
160
|
+
"""
|
|
161
|
+
return platform.chat_until_success(prompt)
|
|
162
|
+
|
|
517
163
|
except Exception as e:
|
|
518
164
|
PrettyOutput.print(f"加载方法论失败: {str(e)}", OutputType.ERROR)
|
|
165
|
+
# 清理临时文件
|
|
166
|
+
if 'temp_file_path' in locals() and temp_file_path and os.path.exists(temp_file_path):
|
|
167
|
+
try:
|
|
168
|
+
os.remove(temp_file_path)
|
|
169
|
+
except:
|
|
170
|
+
pass
|
|
519
171
|
return ""
|
|
172
|
+
finally:
|
|
173
|
+
# 确保清理临时文件
|
|
174
|
+
if 'temp_file_path' in locals() and temp_file_path and os.path.exists(temp_file_path):
|
|
175
|
+
try:
|
|
176
|
+
os.remove(temp_file_path)
|
|
177
|
+
except:
|
|
178
|
+
pass
|