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