jarvis-ai-assistant 0.1.134__py3-none-any.whl → 0.1.138__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.

Files changed (78) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +201 -79
  3. jarvis/jarvis_agent/builtin_input_handler.py +16 -6
  4. jarvis/jarvis_agent/file_input_handler.py +9 -9
  5. jarvis/jarvis_agent/jarvis.py +10 -10
  6. jarvis/jarvis_agent/main.py +12 -11
  7. jarvis/jarvis_agent/output_handler.py +3 -3
  8. jarvis/jarvis_agent/patch.py +86 -62
  9. jarvis/jarvis_agent/shell_input_handler.py +5 -3
  10. jarvis/jarvis_code_agent/code_agent.py +134 -99
  11. jarvis/jarvis_code_agent/file_select.py +24 -24
  12. jarvis/jarvis_dev/main.py +45 -51
  13. jarvis/jarvis_git_details/__init__.py +0 -0
  14. jarvis/jarvis_git_details/main.py +179 -0
  15. jarvis/jarvis_git_squash/main.py +7 -7
  16. jarvis/jarvis_lsp/base.py +11 -11
  17. jarvis/jarvis_lsp/cpp.py +14 -14
  18. jarvis/jarvis_lsp/go.py +13 -13
  19. jarvis/jarvis_lsp/python.py +8 -8
  20. jarvis/jarvis_lsp/registry.py +21 -21
  21. jarvis/jarvis_lsp/rust.py +15 -15
  22. jarvis/jarvis_methodology/main.py +101 -0
  23. jarvis/jarvis_multi_agent/__init__.py +11 -11
  24. jarvis/jarvis_multi_agent/main.py +6 -6
  25. jarvis/jarvis_platform/__init__.py +1 -1
  26. jarvis/jarvis_platform/ai8.py +67 -89
  27. jarvis/jarvis_platform/base.py +14 -13
  28. jarvis/jarvis_platform/kimi.py +25 -28
  29. jarvis/jarvis_platform/ollama.py +24 -26
  30. jarvis/jarvis_platform/openai.py +15 -19
  31. jarvis/jarvis_platform/oyi.py +48 -50
  32. jarvis/jarvis_platform/registry.py +27 -28
  33. jarvis/jarvis_platform/yuanbao.py +38 -42
  34. jarvis/jarvis_platform_manager/main.py +81 -81
  35. jarvis/jarvis_platform_manager/openai_test.py +21 -21
  36. jarvis/jarvis_rag/file_processors.py +18 -18
  37. jarvis/jarvis_rag/main.py +261 -277
  38. jarvis/jarvis_smart_shell/main.py +12 -12
  39. jarvis/jarvis_tools/ask_codebase.py +28 -28
  40. jarvis/jarvis_tools/ask_user.py +8 -8
  41. jarvis/jarvis_tools/base.py +4 -4
  42. jarvis/jarvis_tools/chdir.py +9 -9
  43. jarvis/jarvis_tools/code_review.py +19 -19
  44. jarvis/jarvis_tools/create_code_agent.py +15 -15
  45. jarvis/jarvis_tools/execute_python_script.py +3 -3
  46. jarvis/jarvis_tools/execute_shell.py +11 -11
  47. jarvis/jarvis_tools/execute_shell_script.py +3 -3
  48. jarvis/jarvis_tools/file_analyzer.py +29 -29
  49. jarvis/jarvis_tools/file_operation.py +22 -20
  50. jarvis/jarvis_tools/find_caller.py +25 -25
  51. jarvis/jarvis_tools/find_methodolopy.py +65 -0
  52. jarvis/jarvis_tools/find_symbol.py +24 -24
  53. jarvis/jarvis_tools/function_analyzer.py +27 -27
  54. jarvis/jarvis_tools/git_commiter.py +9 -9
  55. jarvis/jarvis_tools/lsp_get_diagnostics.py +19 -19
  56. jarvis/jarvis_tools/methodology.py +23 -62
  57. jarvis/jarvis_tools/project_analyzer.py +29 -33
  58. jarvis/jarvis_tools/rag.py +15 -15
  59. jarvis/jarvis_tools/read_code.py +24 -22
  60. jarvis/jarvis_tools/read_webpage.py +31 -31
  61. jarvis/jarvis_tools/registry.py +72 -52
  62. jarvis/jarvis_tools/tool_generator.py +18 -18
  63. jarvis/jarvis_utils/config.py +23 -23
  64. jarvis/jarvis_utils/embedding.py +83 -83
  65. jarvis/jarvis_utils/git_utils.py +20 -20
  66. jarvis/jarvis_utils/globals.py +18 -6
  67. jarvis/jarvis_utils/input.py +10 -9
  68. jarvis/jarvis_utils/methodology.py +140 -136
  69. jarvis/jarvis_utils/output.py +11 -11
  70. jarvis/jarvis_utils/utils.py +22 -70
  71. {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/METADATA +1 -1
  72. jarvis_ai_assistant-0.1.138.dist-info/RECORD +85 -0
  73. {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/entry_points.txt +2 -0
  74. jarvis/jarvis_tools/select_code_files.py +0 -62
  75. jarvis_ai_assistant-0.1.134.dist-info/RECORD +0 -82
  76. {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/LICENSE +0 -0
  77. {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/WHEEL +0 -0
  78. {jarvis_ai_assistant-0.1.134.dist-info → jarvis_ai_assistant-0.1.138.dist-info}/top_level.txt +0 -0
@@ -26,7 +26,7 @@ _methodology_index_cache: Optional[Tuple[faiss.IndexIDMap, List[Dict[str, str]],
26
26
  def _get_cache_directory() -> str:
27
27
  """
28
28
  获取缓存目录路径,如果不存在则创建
29
-
29
+
30
30
  返回:
31
31
  str: 缓存目录的路径
32
32
  """
@@ -41,7 +41,7 @@ def _get_cache_directory() -> str:
41
41
  def _get_embeddings_cache_path() -> str:
42
42
  """
43
43
  获取嵌入向量缓存文件的路径
44
-
44
+
45
45
  返回:
46
46
  str: 嵌入向量缓存文件的路径
47
47
  """
@@ -50,7 +50,7 @@ def _get_embeddings_cache_path() -> str:
50
50
  def _get_index_cache_path() -> str:
51
51
  """
52
52
  获取索引缓存文件的路径
53
-
53
+
54
54
  返回:
55
55
  str: 索引缓存文件的路径
56
56
  """
@@ -59,7 +59,7 @@ def _get_index_cache_path() -> str:
59
59
  def _get_index_metadata_path() -> str:
60
60
  """
61
61
  获取索引元数据文件的路径
62
-
62
+
63
63
  返回:
64
64
  str: 索引元数据文件的路径
65
65
  """
@@ -68,14 +68,14 @@ def _get_index_metadata_path() -> str:
68
68
  def _load_embeddings_cache() -> Dict[int, np.ndarray]:
69
69
  """
70
70
  从文件系统加载嵌入向量缓存
71
-
71
+
72
72
  返回:
73
73
  Dict[int, np.ndarray]: 嵌入向量缓存字典
74
74
  """
75
75
  cache_path = _get_embeddings_cache_path()
76
76
  if not os.path.exists(cache_path):
77
77
  return {}
78
-
78
+
79
79
  try:
80
80
  with open(cache_path, "rb") as f:
81
81
  embeddings_cache = pickle.load(f)
@@ -86,18 +86,18 @@ def _load_embeddings_cache() -> Dict[int, np.ndarray]:
86
86
  def _save_embeddings_cache(cache: Dict[int, np.ndarray]) -> bool:
87
87
  """
88
88
  将嵌入向量缓存保存到文件系统
89
-
89
+
90
90
  参数:
91
91
  cache: 要保存的嵌入向量缓存字典
92
-
92
+
93
93
  返回:
94
94
  bool: 保存是否成功
95
95
  """
96
96
  if not cache:
97
97
  return False
98
-
98
+
99
99
  cache_path = _get_embeddings_cache_path()
100
-
100
+
101
101
  try:
102
102
  with open(cache_path, "wb") as f:
103
103
  pickle.dump(cache, f)
@@ -109,62 +109,62 @@ def _save_embeddings_cache(cache: Dict[int, np.ndarray]) -> bool:
109
109
  def _load_index_cache() -> Optional[Tuple[faiss.IndexIDMap, List[Dict[str, str]], str]]:
110
110
  """
111
111
  从文件系统加载索引缓存
112
-
112
+
113
113
  返回:
114
114
  Optional[Tuple[faiss.IndexIDMap, List[Dict[str, str]], str]]: 索引缓存元组
115
115
  """
116
116
  index_path = _get_index_cache_path()
117
117
  metadata_path = _get_index_metadata_path()
118
-
118
+
119
119
  if not os.path.exists(index_path) or not os.path.exists(metadata_path):
120
120
  return None
121
-
121
+
122
122
  try:
123
123
  # 加载索引
124
124
  index = faiss.read_index(index_path)
125
-
125
+
126
126
  # 加载元数据
127
127
  with open(metadata_path, "rb") as f:
128
128
  metadata = pickle.load(f)
129
-
129
+
130
130
  methodology_data = metadata.get("methodology_data", [])
131
131
  methodology_hash = metadata.get("methodology_hash", "")
132
-
132
+
133
133
  if isinstance(index, faiss.IndexIDMap) and methodology_data and methodology_hash:
134
134
  return index, methodology_data, methodology_hash
135
135
  except Exception as e:
136
136
  PrettyOutput.print(f"加载索引缓存失败: {str(e)}", OutputType.WARNING)
137
-
137
+
138
138
  return None
139
139
 
140
140
  def _save_index_cache(index: faiss.IndexIDMap, methodology_data: List[Dict[str, str]], methodology_hash: str) -> bool:
141
141
  """
142
142
  将索引缓存保存到文件系统
143
-
143
+
144
144
  参数:
145
145
  index: FAISS索引
146
146
  methodology_data: 方法论数据列表
147
147
  methodology_hash: 方法论文件哈希值
148
-
148
+
149
149
  返回:
150
150
  bool: 保存是否成功
151
151
  """
152
152
  index_path = _get_index_cache_path()
153
153
  metadata_path = _get_index_metadata_path()
154
-
154
+
155
155
  try:
156
156
  # 保存索引
157
157
  faiss.write_index(index, index_path)
158
-
158
+
159
159
  # 保存元数据
160
160
  metadata = {
161
161
  "methodology_data": methodology_data,
162
162
  "methodology_hash": methodology_hash
163
163
  }
164
-
164
+
165
165
  with open(metadata_path, "wb") as f:
166
166
  pickle.dump(metadata, f)
167
-
167
+
168
168
  return True
169
169
  except Exception as e:
170
170
  PrettyOutput.print(f"保存索引缓存失败: {str(e)}", OutputType.WARNING)
@@ -173,11 +173,11 @@ def _save_index_cache(index: faiss.IndexIDMap, methodology_data: List[Dict[str,
173
173
  def _create_methodology_embedding(embedding_model: Any, methodology_text: str) -> np.ndarray:
174
174
  """
175
175
  为方法论文本创建嵌入向量。
176
-
176
+
177
177
  参数:
178
178
  embedding_model: 使用的嵌入模型
179
179
  methodology_text: 要创建嵌入的文本
180
-
180
+
181
181
  返回:
182
182
  np.ndarray: 嵌入向量
183
183
  """
@@ -186,21 +186,21 @@ def _create_methodology_embedding(embedding_model: Any, methodology_text: str) -
186
186
  cache_key = hash(methodology_text)
187
187
  if cache_key in _methodology_embeddings_cache:
188
188
  return _methodology_embeddings_cache[cache_key]
189
-
189
+
190
190
  # 截断长文本
191
191
  max_length = 512
192
192
  text = ' '.join(methodology_text.split()[:max_length])
193
-
193
+
194
194
  # 使用sentence_transformers模型获取嵌入向量
195
- embedding = embedding_model.encode([text],
195
+ embedding = embedding_model.encode([text],
196
196
  convert_to_tensor=True,
197
197
  normalize_embeddings=True)
198
198
  vector = np.array(embedding.cpu().numpy(), dtype=np.float32)
199
199
  result = vector[0] # 返回第一个向量,因为我们只编码了一个文本
200
-
200
+
201
201
  # 缓存嵌入向量以便后续使用
202
202
  _methodology_embeddings_cache[cache_key] = result
203
-
203
+
204
204
  return result
205
205
  except Exception as e:
206
206
  PrettyOutput.print(f"创建方法论嵌入向量失败: {str(e)}", OutputType.ERROR)
@@ -209,14 +209,14 @@ def _create_methodology_embedding(embedding_model: Any, methodology_text: str) -
209
209
  def make_methodology_prompt(data: Dict[str, str]) -> str:
210
210
  """
211
211
  从方法论数据生成格式化提示
212
-
212
+
213
213
  参数:
214
214
  data: 方法论数据字典
215
-
215
+
216
216
  返回:
217
217
  str: 格式化后的提示字符串
218
218
  """
219
- ret = """这是处理以往问题的标准方法论,如果当前任务类似,可以参考使用,如果不相关,请忽略:\n"""
219
+ ret = """这是处理以往问题的标准方法论,如果当前任务类似,可以参考使用,如果不相关,请忽略:\n"""
220
220
  for key, value in data.items():
221
221
  ret += f"问题: {key}\n方法论: {value}\n"
222
222
  return ret
@@ -224,7 +224,7 @@ def make_methodology_prompt(data: Dict[str, str]) -> str:
224
224
  def _get_methodology_directory() -> str:
225
225
  """
226
226
  获取方法论目录路径,如果不存在则创建
227
-
227
+
228
228
  返回:
229
229
  str: 方法论目录的路径
230
230
  """
@@ -239,46 +239,46 @@ def _get_methodology_directory() -> str:
239
239
  def _get_methodology_files_hash() -> str:
240
240
  """
241
241
  计算所有方法论文件的组合哈希值,用于检测文件变化
242
-
242
+
243
243
  返回:
244
244
  str: 所有方法论文件的组合哈希值
245
245
  """
246
246
  methodology_dir = _get_methodology_directory()
247
247
  if not os.path.exists(methodology_dir):
248
248
  return ""
249
-
249
+
250
250
  # 获取所有方法论文件的路径和修改时间
251
251
  files_data = []
252
252
  for filepath in glob.glob(os.path.join(methodology_dir, "*.json")):
253
253
  mtime = os.path.getmtime(filepath)
254
254
  files_data.append((filepath, mtime))
255
-
255
+
256
256
  # 按路径排序,保证哈希值的一致性
257
257
  files_data.sort(key=lambda x: x[0])
258
-
258
+
259
259
  # 计算组合哈希值
260
260
  if not files_data:
261
261
  return ""
262
-
262
+
263
263
  hasher = hashlib.md5()
264
264
  for filepath, mtime in files_data:
265
265
  hasher.update(f"{filepath}:{mtime}".encode("utf-8"))
266
-
266
+
267
267
  return hasher.hexdigest()
268
268
 
269
269
  def _load_all_methodologies() -> Dict[str, str]:
270
270
  """
271
271
  加载所有方法论文件
272
-
272
+
273
273
  返回:
274
274
  Dict[str, str]: 方法论字典,键为问题类型,值为方法论内容
275
275
  """
276
276
  methodology_dir = _get_methodology_directory()
277
277
  all_methodologies = {}
278
-
278
+
279
279
  if not os.path.exists(methodology_dir):
280
280
  return all_methodologies
281
-
281
+
282
282
  for filepath in glob.glob(os.path.join(methodology_dir, "*.json")):
283
283
  try:
284
284
  with open(filepath, "r", encoding="utf-8", errors="ignore") as f:
@@ -290,7 +290,7 @@ def _load_all_methodologies() -> Dict[str, str]:
290
290
  except Exception as e:
291
291
  filename = os.path.basename(filepath)
292
292
  PrettyOutput.print(f"加载方法论文件 {filename} 失败: {str(e)}", OutputType.WARNING)
293
-
293
+
294
294
  return all_methodologies
295
295
 
296
296
  def _migrate_from_old_format():
@@ -300,34 +300,34 @@ def _migrate_from_old_format():
300
300
  old_format_file = os.path.expanduser("~/.jarvis/methodology")
301
301
  if not os.path.exists(old_format_file):
302
302
  return
303
-
303
+
304
304
  try:
305
305
  # 加载旧格式文件
306
306
  with open(old_format_file, "r", encoding="utf-8", errors="ignore") as f:
307
307
  old_data = yaml.safe_load(f) or {}
308
-
308
+
309
309
  if not old_data:
310
310
  return
311
-
311
+
312
312
  # 创建新目录
313
313
  methodology_dir = _get_methodology_directory()
314
-
314
+
315
315
  # 迁移每个方法论
316
316
  migrated_count = 0
317
317
  for problem_type, content in old_data.items():
318
318
  # 为每个方法论创建文件名(使用问题类型的MD5哈希作为文件名)
319
319
  safe_filename = hashlib.md5(problem_type.encode('utf-8')).hexdigest()
320
320
  file_path = os.path.join(methodology_dir, f"{safe_filename}.json")
321
-
321
+
322
322
  # 保存为新格式
323
323
  with open(file_path, "w", encoding="utf-8", errors="ignore") as f:
324
324
  json.dump({
325
325
  "problem_type": problem_type,
326
326
  "content": content
327
327
  }, f, ensure_ascii=False, indent=2)
328
-
328
+
329
329
  migrated_count += 1
330
-
330
+
331
331
  if migrated_count > 0:
332
332
  # 备份旧文件
333
333
  backup_path = old_format_file + ".bak"
@@ -342,15 +342,15 @@ def _migrate_from_old_format():
342
342
  def load_methodology(user_input: str) -> str:
343
343
  """
344
344
  加载方法论并构建向量索引以进行相似性搜索。
345
-
345
+
346
346
  参数:
347
347
  user_input: 要搜索方法论的输入文本
348
-
348
+
349
349
  返回:
350
350
  str: 相关的方法论提示,如果未找到方法论则返回空字符串
351
351
  """
352
352
  from yaspin import yaspin
353
-
353
+
354
354
  # 加载嵌入向量缓存
355
355
  global _methodology_embeddings_cache
356
356
  if not _methodology_embeddings_cache:
@@ -358,22 +358,22 @@ def load_methodology(user_input: str) -> str:
358
358
  _methodology_embeddings_cache = _load_embeddings_cache()
359
359
  spinner.text = f"加载嵌入向量缓存完成 ({len(_methodology_embeddings_cache)} 个向量)"
360
360
  spinner.ok("✅")
361
-
361
+
362
362
  # 检查是否需要从旧格式迁移
363
363
  with yaspin(text="检查方法论格式...", color="yellow") as spinner:
364
364
  _migrate_from_old_format()
365
365
  spinner.text = "检查方法论格式完成"
366
366
  spinner.ok("✅")
367
-
367
+
368
368
  # 获取方法论目录
369
369
  methodology_dir = _get_methodology_directory()
370
370
  if not os.path.exists(methodology_dir) or not glob.glob(os.path.join(methodology_dir, "*.json")):
371
371
  return ""
372
-
372
+
373
373
  try:
374
374
  # 获取文件的修改时间戳组合哈希,用于检测文件是否被修改
375
375
  methodology_hash = _get_methodology_files_hash()
376
-
376
+
377
377
  # 检查缓存的索引是否可用且方法论文件未被修改
378
378
  global _methodology_index_cache
379
379
  if _methodology_index_cache is None:
@@ -386,7 +386,7 @@ def load_methodology(user_input: str) -> str:
386
386
  else:
387
387
  spinner.text = "没有可用的索引缓存"
388
388
  spinner.fail("❌")
389
-
389
+
390
390
  if _methodology_index_cache is not None:
391
391
  cached_index, cached_data, cache_hash = _methodology_index_cache
392
392
  if cache_hash == methodology_hash:
@@ -396,12 +396,12 @@ def load_methodology(user_input: str) -> str:
396
396
  methodology_data = cached_data
397
397
  spinner.text = "使用缓存的方法论索引完成"
398
398
  spinner.ok("✅")
399
-
399
+
400
400
  with yaspin(text="加载嵌入模型...", color="yellow") as spinner:
401
401
  embedding_model = load_embedding_model()
402
402
  spinner.text = "加载嵌入模型完成"
403
403
  spinner.ok("✅")
404
-
404
+
405
405
  with yaspin(text="执行搜索...", color="yellow") as spinner:
406
406
  # 使用缓存构造输入文本的嵌入
407
407
  query_embedding = _create_methodology_embedding(embedding_model, user_input)
@@ -411,7 +411,7 @@ def load_methodology(user_input: str) -> str:
411
411
  ) # type: ignore
412
412
  spinner.text = "执行搜索完成"
413
413
  spinner.ok("✅")
414
-
414
+
415
415
  with yaspin(text="处理搜索结果...", color="yellow") as spinner:
416
416
  relevant_methodologies = {}
417
417
  for dist, idx in zip(distances[0], indices[0]):
@@ -422,10 +422,12 @@ def load_methodology(user_input: str) -> str:
422
422
  relevant_methodologies[methodology["key"]] = methodology["value"]
423
423
  spinner.text = "处理搜索结果完成"
424
424
  spinner.ok("✅")
425
-
425
+
426
426
  if relevant_methodologies:
427
+ spinner.text = f"找到相关方法论: {', '.join(relevant_methodologies.keys())}"
428
+ spinner.ok("✅")
427
429
  return make_methodology_prompt(relevant_methodologies)
428
-
430
+
429
431
  # 如果缓存无效,从头构建索引
430
432
  with yaspin(text="初始化数据结构...", color="yellow") as spinner:
431
433
  methodology_data: List[Dict[str, str]] = []
@@ -433,83 +435,85 @@ def load_methodology(user_input: str) -> str:
433
435
  ids: List[int] = []
434
436
  spinner.text = "初始化数据结构完成"
435
437
  spinner.ok("✅")
436
-
437
- with yaspin(text="加载嵌入模型...", color="yellow") as spinner:
438
- embedding_model = load_embedding_model()
439
- spinner.text = "加载嵌入模型完成"
440
- spinner.ok("✅")
441
-
442
- with yaspin(text="创建测试嵌入...", color="yellow") as spinner:
443
- test_embedding = _create_methodology_embedding(embedding_model, "test")
444
- embedding_dimension = len(test_embedding)
445
- spinner.text = "创建测试嵌入完成"
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
+
450
+ with yaspin(text="加载方法论文件...", color="yellow") as spinner:
451
+ data = _load_all_methodologies()
452
+ spinner.text = "加载方法论文件完成"
453
+ spinner.ok("✅")
454
+
455
+ with yaspin(text="处理方法论数据...", color="yellow") as spinner:
456
+ for i, (key, value) in enumerate(data.items()):
457
+ methodology_text = f"{key}\n{value}"
458
+ embedding = _create_methodology_embedding(embedding_model, methodology_text)
459
+ vectors.append(embedding)
460
+ ids.append(i)
461
+ methodology_data.append({"key": key, "value": value})
462
+ spinner.text = "处理方法论数据完成"
463
+ spinner.ok("✅")
464
+
465
+ if vectors:
466
+ with yaspin(text="构建索引...", color="yellow") as spinner:
467
+ vectors_array = np.vstack(vectors)
468
+ hnsw_index = faiss.IndexHNSWFlat(embedding_dimension, 16)
469
+ hnsw_index.hnsw.efConstruction = 40
470
+ hnsw_index.hnsw.efSearch = 16
471
+ methodology_index = faiss.IndexIDMap(hnsw_index)
472
+ methodology_index.add_with_ids(vectors_array, np.array(ids)) # type: ignore
473
+ # 缓存构建好的索引和数据以及时间戳哈希
474
+ _methodology_index_cache = (methodology_index, methodology_data, methodology_hash)
475
+
476
+ # 将索引和嵌入向量缓存保存到文件系统
477
+ _save_index_cache(methodology_index, methodology_data, methodology_hash)
478
+
479
+ spinner.text = "构建索引完成"
446
480
  spinner.ok("✅")
447
481
 
448
- with yaspin(text="加载方法论文件...", color="yellow") as spinner:
449
- data = _load_all_methodologies()
450
- spinner.text = "加载方法论文件完成"
482
+ with yaspin(text="执行搜索...", color="yellow") as spinner:
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 = "执行搜索完成"
451
489
  spinner.ok("✅")
452
-
453
- with yaspin(text="处理方法论数据...", color="yellow") as spinner:
454
- for i, (key, value) in enumerate(data.items()):
455
- methodology_text = f"{key}\n{value}"
456
- embedding = _create_methodology_embedding(embedding_model, methodology_text)
457
- vectors.append(embedding)
458
- ids.append(i)
459
- methodology_data.append({"key": key, "value": value})
460
- spinner.text = "处理方法论数据完成"
490
+
491
+ with yaspin(text="处理搜索结果...", color="yellow") as spinner:
492
+ relevant_methodologies = {}
493
+ for dist, idx in zip(distances[0], indices[0]):
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 = "处理搜索结果完成"
461
500
  spinner.ok("✅")
462
-
463
- if vectors:
464
- with yaspin(text="构建索引...", color="yellow") as spinner:
465
- vectors_array = np.vstack(vectors)
466
- hnsw_index = faiss.IndexHNSWFlat(embedding_dimension, 16)
467
- hnsw_index.hnsw.efConstruction = 40
468
- hnsw_index.hnsw.efSearch = 16
469
- methodology_index = faiss.IndexIDMap(hnsw_index)
470
- methodology_index.add_with_ids(vectors_array, np.array(ids)) # type: ignore
471
- # 缓存构建好的索引和数据以及时间戳哈希
472
- _methodology_index_cache = (methodology_index, methodology_data, methodology_hash)
473
-
474
- # 将索引和嵌入向量缓存保存到文件系统
475
- _save_index_cache(methodology_index, methodology_data, methodology_hash)
476
-
477
- spinner.text = "构建索引完成"
478
- spinner.ok("✅")
479
-
480
- with yaspin(text="执行搜索...", color="yellow") as spinner:
481
- query_embedding = _create_methodology_embedding(embedding_model, user_input)
482
- k = min(10, len(methodology_data))
483
- distances, indices = methodology_index.search(
484
- query_embedding.reshape(1, -1), k
485
- ) # type: ignore
486
- spinner.text = "执行搜索完成"
487
- spinner.ok("✅")
488
-
489
- with yaspin(text="处理搜索结果...", color="yellow") as spinner:
490
- relevant_methodologies = {}
491
- for dist, idx in zip(distances[0], indices[0]):
492
- if idx >= 0:
493
- similarity = 1.0 / (1.0 + float(dist))
494
- methodology = methodology_data[idx]
495
- if similarity >= 0.5:
496
- relevant_methodologies[methodology["key"]] = methodology["value"]
497
- spinner.text = "处理搜索结果完成"
501
+
502
+ # 保存嵌入向量缓存到文件系统
503
+ with yaspin(text="保存嵌入向量缓存...", color="yellow") as spinner:
504
+ if _save_embeddings_cache(_methodology_embeddings_cache):
505
+ spinner.text = f"保存嵌入向量缓存完成 ({len(_methodology_embeddings_cache)} 个向量)"
498
506
  spinner.ok("✅")
499
-
500
- # 保存嵌入向量缓存到文件系统
501
- with yaspin(text="保存嵌入向量缓存...", color="yellow") as spinner:
502
- if _save_embeddings_cache(_methodology_embeddings_cache):
503
- spinner.text = f"保存嵌入向量缓存完成 ({len(_methodology_embeddings_cache)} 个向量)"
504
- spinner.ok("")
505
- else:
506
- spinner.text = "保存嵌入向量缓存失败"
507
- spinner.fail("❌")
508
-
509
- if relevant_methodologies:
510
- return make_methodology_prompt(relevant_methodologies)
511
-
512
- return make_methodology_prompt(data)
507
+ else:
508
+ spinner.text = "保存嵌入向量缓存失败"
509
+ spinner.fail("")
510
+
511
+ if relevant_methodologies:
512
+ spinner.write(f"找到相关方法论: {', '.join(relevant_methodologies.keys())}")
513
+ return make_methodology_prompt(relevant_methodologies)
514
+ spinner.write(f"未找到相关的方法论")
515
+ spinner.fail("❌")
516
+ return ""
513
517
  except Exception as e:
514
518
  PrettyOutput.print(f"加载方法论失败: {str(e)}", OutputType.ERROR)
515
519
  return ""
@@ -21,7 +21,7 @@ from jarvis.jarvis_utils.globals import console, get_agent_list
21
21
  class OutputType(Enum):
22
22
  """
23
23
  输出类型枚举,用于分类和样式化不同类型的消息。
24
-
24
+
25
25
  属性:
26
26
  SYSTEM: AI助手消息
27
27
  CODE: 代码相关输出
@@ -51,7 +51,7 @@ class OutputType(Enum):
51
51
  class PrettyOutput:
52
52
  """
53
53
  使用rich库格式化和显示富文本输出的类。
54
-
54
+
55
55
  提供以下方法:
56
56
  - 使用适当的样式格式化不同类型的输出
57
57
  - 代码块的语法高亮
@@ -110,11 +110,11 @@ class PrettyOutput:
110
110
  def _detect_language(text: str, default_lang: str = 'markdown') -> str:
111
111
  """
112
112
  检测给定文本的编程语言。
113
-
113
+
114
114
  参数:
115
115
  text: 要分析的文本
116
116
  default_lang: 如果检测失败,默认返回的语言
117
-
117
+
118
118
  返回:
119
119
  str: 检测到的语言名称
120
120
  """
@@ -128,11 +128,11 @@ class PrettyOutput:
128
128
  def _format(output_type: OutputType, timestamp: bool = True) -> Text:
129
129
  """
130
130
  使用时间戳和图标格式化输出头。
131
-
131
+
132
132
  参数:
133
133
  output_type: 输出类型
134
134
  timestamp: 是否包含时间戳
135
-
135
+
136
136
  返回:
137
137
  Text: 格式化后的rich Text对象
138
138
  """
@@ -149,7 +149,7 @@ class PrettyOutput:
149
149
  def print(text: str, output_type: OutputType, timestamp: bool = True, lang: Optional[str] = None, traceback: bool = False):
150
150
  """
151
151
  使用样式和语法高亮打印格式化输出。
152
-
152
+
153
153
  参数:
154
154
  text: 要打印的文本内容
155
155
  output_type: 输出类型(影响样式)
@@ -192,7 +192,7 @@ class PrettyOutput:
192
192
  def section(title: str, output_type: OutputType = OutputType.INFO):
193
193
  """
194
194
  在样式化面板中打印章节标题。
195
-
195
+
196
196
  参数:
197
197
  title: 章节标题文本
198
198
  output_type: 输出类型(影响样式)
@@ -208,7 +208,7 @@ class PrettyOutput:
208
208
  def print_stream(text: str, is_thinking: bool = False):
209
209
  """
210
210
  打印流式输出,不带换行符。
211
-
211
+
212
212
  参数:
213
213
  text: 要打印的文本
214
214
  """
@@ -228,10 +228,10 @@ class PrettyOutput:
228
228
  def _get_style(output_type: OutputType) -> RichStyle:
229
229
  """
230
230
  获取预定义的RichStyle用于输出类型。
231
-
231
+
232
232
  参数:
233
233
  output_type: 要获取样式的输出类型
234
-
234
+
235
235
  返回:
236
236
  RichStyle: 对应的样式
237
237
  """