jarvis-ai-assistant 0.1.67__tar.gz → 0.1.73__tar.gz

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 (40) hide show
  1. {jarvis_ai_assistant-0.1.67/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.73}/PKG-INFO +4 -3
  2. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/pyproject.toml +4 -3
  3. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/setup.py +4 -3
  4. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/__init__.py +1 -1
  5. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/jarvis_codebase/main.py +107 -24
  6. jarvis_ai_assistant-0.1.73/src/jarvis/jarvis_coder/__init__.py +0 -0
  7. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/jarvis_coder/main.py +41 -10
  8. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/models/registry.py +1 -1
  9. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/codebase_qa.py +3 -0
  10. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/registry.py +1 -1
  11. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/utils.py +1 -1
  12. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73/src/jarvis_ai_assistant.egg-info}/PKG-INFO +4 -3
  13. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +1 -0
  14. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis_ai_assistant.egg-info/requires.txt +3 -2
  15. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/LICENSE +0 -0
  16. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/MANIFEST.in +0 -0
  17. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/README.md +0 -0
  18. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/setup.cfg +0 -0
  19. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/agent.py +0 -0
  20. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/jarvis_codebase/__init__.py +0 -0
  21. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/main.py +0 -0
  22. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/models/__init__.py +0 -0
  23. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/models/ai8.py +0 -0
  24. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/models/base.py +0 -0
  25. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/models/kimi.py +0 -0
  26. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/models/openai.py +0 -0
  27. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/models/oyi.py +0 -0
  28. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/__init__.py +0 -0
  29. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/base.py +0 -0
  30. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/coder.py +0 -0
  31. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/file_ops.py +0 -0
  32. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/generator.py +0 -0
  33. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/methodology.py +0 -0
  34. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/search.py +0 -0
  35. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/shell.py +0 -0
  36. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/sub_agent.py +0 -0
  37. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis/tools/webpage.py +0 -0
  38. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
  39. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
  40. {jarvis_ai_assistant-0.1.67 → jarvis_ai_assistant-0.1.73}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.67
3
+ Version: 0.1.73
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire
@@ -44,9 +44,10 @@ Requires-Dist: colorama>=0.4.6
44
44
  Requires-Dist: prompt_toolkit>=3.0.0
45
45
  Requires-Dist: openai>=1.20.0
46
46
  Requires-Dist: playwright>=1.41.1
47
- Requires-Dist: numpy>=1.26.0
48
- Requires-Dist: faiss-cpu>=1.8.1
47
+ Requires-Dist: numpy>=1.24.0
48
+ Requires-Dist: faiss-cpu>=1.8.0
49
49
  Requires-Dist: sentence-transformers>=2.2.2
50
+ Requires-Dist: bs4>=0.0.1
50
51
  Provides-Extra: dev
51
52
  Requires-Dist: pytest; extra == "dev"
52
53
  Requires-Dist: black; extra == "dev"
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "jarvis-ai-assistant"
7
- version = "0.1.67"
7
+ version = "0.1.73"
8
8
  description = "Jarvis: An AI assistant that uses tools to interact with the system"
9
9
  readme = "README.md"
10
10
  authors = [{ name = "Your Name", email = "your.email@example.com" }]
@@ -26,9 +26,10 @@ dependencies = [
26
26
  "prompt_toolkit>=3.0.0",
27
27
  "openai>=1.20.0",
28
28
  "playwright>=1.41.1",
29
- "numpy>=1.26.0",
30
- "faiss-cpu>=1.8.1",
29
+ "numpy>=1.24.0",
30
+ "faiss-cpu>=1.8.0",
31
31
  "sentence-transformers>=2.2.2",
32
+ "bs4>=0.0.1",
32
33
  ]
33
34
  requires-python = ">=3.8"
34
35
 
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="jarvis-ai-assistant",
5
- version="0.1.67",
5
+ version="0.1.73",
6
6
  author="skyfire",
7
7
  author_email="skyfireitdiy@hotmail.com",
8
8
  description="An AI assistant that uses various tools to interact with the system",
@@ -19,9 +19,10 @@ setup(
19
19
  "prompt_toolkit>=3.0.0",
20
20
  "openai>=1.20.0",
21
21
  "playwright>=1.41.1",
22
- "numpy>=1.26.0",
23
- "faiss-cpu>=1.8.1",
22
+ "numpy>=1.24.0",
23
+ "faiss-cpu>=1.8.0",
24
24
  "sentence-transformers>=2.2.2",
25
+ "bs4>=0.0.1",
25
26
  ],
26
27
  entry_points={
27
28
  "console_scripts": [
@@ -1,3 +1,3 @@
1
1
  """Jarvis AI Assistant"""
2
2
 
3
- __version__ = "0.1.67"
3
+ __version__ = "0.1.73"
@@ -18,18 +18,22 @@ class CodeBase:
18
18
  load_env_from_file()
19
19
  self.root_dir = root_dir
20
20
  os.chdir(self.root_dir)
21
- self.thread_count = os.environ.get("JARVIS_THREAD_COUNT") or 10
21
+ self.thread_count = int(os.environ.get("JARVIS_THREAD_COUNT") or 10)
22
22
  self.cheap_platform = os.environ.get("JARVIS_CHEAP_PLATFORM") or os.environ.get("JARVIS_PLATFORM") or "kimi"
23
23
  self.cheap_model = os.environ.get("JARVIS_CHEAP_MODEL") or os.environ.get("JARVIS_MODEL") or "kimi"
24
24
  self.normal_platform = os.environ.get("JARVIS_PLATFORM") or "kimi"
25
+ self.codegen_platform = os.environ.get("JARVIS_CODEGEN_PLATFORM") or os.environ.get("JARVIS_PLATFORM") or "kimi"
26
+ self.codegen_model = os.environ.get("JARVIS_CODEGEN_MODEL") or os.environ.get("JARVIS_MODEL") or "kimi"
25
27
  self.normal_model = os.environ.get("JARVIS_MODEL") or "kimi"
26
28
  self.embedding_model_name = os.environ.get("JARVIS_EMBEDDING_MODEL") or "BAAI/bge-large-zh-v1.5"
27
- if not self.cheap_platform or not self.cheap_model or not self.embedding_model_name or not self.normal_platform or not self.normal_model:
28
- raise ValueError("JARVIS_CHEAP_PLATFORM or JARVIS_CHEAP_MODEL or JARVIS_EMBEDDING_MODEL or JARVIS_PLATFORM or JARVIS_MODEL is not set")
29
+ if not self.cheap_platform or not self.cheap_model or not self.codegen_platform or not self.codegen_model or not self.embedding_model_name or not self.normal_platform or not self.normal_model:
30
+ raise ValueError("JARVIS_CHEAP_PLATFORM or JARVIS_CHEAP_MODEL or JARVIS_CODEGEN_PLATFORM or JARVIS_CODEGEN_MODEL or JARVIS_EMBEDDING_MODEL or JARVIS_PLATFORM or JARVIS_MODEL is not set")
29
31
 
30
32
  PrettyOutput.print(f"廉价模型使用平台: {self.cheap_platform} 模型: {self.cheap_model}", output_type=OutputType.INFO)
33
+ PrettyOutput.print(f"代码生成模型使用平台: {self.codegen_platform} 模型: {self.codegen_model}", output_type=OutputType.INFO)
31
34
  PrettyOutput.print(f"分析模型使用平台: {self.normal_platform} 模型: {self.normal_model}", output_type=OutputType.INFO)
32
35
  PrettyOutput.print(f"嵌入模型: {self.embedding_model_name}", output_type=OutputType.INFO)
36
+ PrettyOutput.print(f"索引建立线程数: {self.thread_count}", output_type=OutputType.INFO)
33
37
  PrettyOutput.print(f"检索算法:分层导航小世界算法", output_type=OutputType.INFO)
34
38
 
35
39
  # 初始化数据目录
@@ -39,6 +43,7 @@ class CodeBase:
39
43
 
40
44
  # 初始化嵌入模型,使用系统默认缓存目录
41
45
  try:
46
+ os.environ["TOKENIZERS_PARALLELISM"] = "false"
42
47
  PrettyOutput.print("正在加载/下载模型,请稍候...", output_type=OutputType.INFO)
43
48
  self.embedding_model = SentenceTransformer(self.embedding_model_name)
44
49
 
@@ -327,7 +332,69 @@ class CodeBase:
327
332
 
328
333
  PrettyOutput.print(f"成功为 {len(processed_files)} 个文件生成索引", output_type=OutputType.INFO)
329
334
 
330
- def search_similar(self, query: str, top_k: int = 5) -> List[Tuple[str, float, str]]:
335
+ def rerank_results(self, query: str, initial_results: List[Tuple[str, float, str]]) -> List[Tuple[str, float, str]]:
336
+ """使用大模型对搜索结果重新排序"""
337
+ if not initial_results:
338
+ return []
339
+
340
+ model = self.platform_registry.create_platform(self.normal_platform)
341
+ model.set_model_name(self.normal_model)
342
+ model.set_suppress_output(True)
343
+
344
+ try:
345
+ # 构建重排序的prompt
346
+ prompt = f"""请根据用户的查询,对以下代码文件进行相关性排序。对每个文件给出0-100的相关性分数,分数越高表示越相关。
347
+ 只需要输出每个文件的分数,格式为:
348
+ <RERANK_START>
349
+ 文件路径: 分数
350
+ 文件路径: 分数
351
+ <RERANK_END>
352
+
353
+ 用户查询: {query}
354
+
355
+ 待评估文件:
356
+ """
357
+ for path, _, desc in initial_results:
358
+ prompt += f"""
359
+ 文件: {path}
360
+ 描述: {desc}
361
+ ---
362
+ """
363
+
364
+ response = model.chat(prompt)
365
+
366
+ # 提取<RERANK_START>和<RERANK_END>之间的内容
367
+ start_tag = "<RERANK_START>"
368
+ end_tag = "<RERANK_END>"
369
+ if start_tag in response and end_tag in response:
370
+ response = response[response.find(start_tag) + len(start_tag):response.find(end_tag)]
371
+
372
+ # 解析响应,提取文件路径和分数
373
+ scored_results = []
374
+ for line in response.split('\n'):
375
+ if ':' not in line:
376
+ continue
377
+ try:
378
+ file_path, score_str = line.split(':', 1)
379
+ file_path = file_path.strip()
380
+ score = float(score_str.strip()) / 100.0 # 转换为0-1范围
381
+ # 只保留相关度大于等于0.7的结果
382
+ if score >= 0.7:
383
+ # 找到对应的原始描述
384
+ desc = next((desc for p, _, desc in initial_results if p == file_path), "")
385
+ scored_results.append((file_path, score, desc))
386
+ except:
387
+ continue
388
+
389
+ # 按分数降序排序
390
+ return sorted(scored_results, key=lambda x: x[1], reverse=True)
391
+
392
+ finally:
393
+ model.delete_chat()
394
+
395
+ return initial_results
396
+
397
+ def search_similar(self, query: str, top_k: int = 20) -> List[Tuple[str, float, str]]:
331
398
  """搜索相似文件"""
332
399
  model = self.platform_registry.create_platform(self.normal_platform)
333
400
  model.set_model_name(self.normal_model)
@@ -348,8 +415,6 @@ class CodeBase:
348
415
  PrettyOutput.print(f"查询: {query}", output_type=OutputType.INFO)
349
416
 
350
417
  # 为每个查询获取相似文件
351
- all_results = {} # 文件路径 -> (总分数, 出现次数, 描述)
352
-
353
418
  q_vector = self.get_embedding(query)
354
419
  q_vector = q_vector.reshape(1, -1)
355
420
 
@@ -357,25 +422,36 @@ class CodeBase:
357
422
 
358
423
  PrettyOutput.print(f"查询 {query} 的结果: ", output_type=OutputType.INFO)
359
424
 
360
- ret = []
425
+ initial_results = []
361
426
 
362
427
  for i, distance in zip(indices[0], distances[0]):
363
428
  if i == -1: # faiss返回-1表示无效结果
364
429
  continue
365
430
 
366
431
  similarity = 1.0 / (1.0 + float(distance))
367
- PrettyOutput.print(f" {self.file_paths[i]} : 距离 {distance:.3f}, 相似度 {similarity:.3f}",
368
- output_type=OutputType.INFO)
432
+ # 只保留相似度大于等于0.5的结果
433
+ if similarity >= 0.5:
434
+ PrettyOutput.print(f" {self.file_paths[i]} : 距离 {distance:.3f}, 相似度 {similarity:.3f}",
435
+ output_type=OutputType.INFO)
369
436
 
370
- file_path = self.file_paths[i]
371
- data = self.vector_cache[file_path]
372
- ret.append((file_path, similarity, data["description"]))
373
- return ret
437
+ file_path = self.file_paths[i]
438
+ data = self.vector_cache[file_path]
439
+ initial_results.append((file_path, similarity, data["description"]))
440
+
441
+ if not initial_results:
442
+ PrettyOutput.print("没有找到相似度大于0.5的文件", output_type=OutputType.WARNING)
443
+ return []
374
444
 
375
- def ask_codebase(self, query: str, top_k: int = 5) -> List[Tuple[str, float, str]]:
445
+ # 使用大模型重新排序
446
+ PrettyOutput.print("使用大模型重新排序...", output_type=OutputType.INFO)
447
+ reranked_results = self.rerank_results(query, initial_results)
448
+
449
+ return reranked_results
450
+
451
+ def ask_codebase(self, query: str, top_k: int=20) -> str:
376
452
  """查询代码库"""
377
453
  results = self.search_similar(query, top_k)
378
- PrettyOutput.print(f"找到的关联文件: ", output_type=OutputType.INFO)
454
+ PrettyOutput.print(f"找到的关联文件: ", output_type=OutputType.SUCCESS)
379
455
  for path, score, _ in results:
380
456
  PrettyOutput.print(f"文件: {path} 关联度: {score:.3f}",
381
457
  output_type=OutputType.INFO)
@@ -384,9 +460,12 @@ class CodeBase:
384
460
  """
385
461
  for path, _, _ in results:
386
462
  try:
463
+ if len(prompt) > 30 * 1024:
464
+ PrettyOutput.print(f"避免上下文超限,丢弃低相关度文件:{path}", OutputType.WARNING)
465
+ continue
387
466
  content = open(path, "r", encoding="utf-8").read()
388
467
  prompt += f"""
389
- 文件路径: {path}
468
+ 文件路径: {path}prompt
390
469
  文件内容:
391
470
  {content}
392
471
  ========================================
@@ -401,8 +480,8 @@ class CodeBase:
401
480
 
402
481
  请用专业的语言回答用户的问题,如果给出的文件内容不足以回答用户的问题,请告诉用户,绝对不要胡编乱造。
403
482
  """
404
- model = self.platform_registry.create_platform(self.normal_platform)
405
- model.set_model_name(self.normal_model)
483
+ model = self.platform_registry.create_platform(self.codegen_platform)
484
+ model.set_model_name(self.codegen_model)
406
485
  try:
407
486
  response = model.chat(prompt)
408
487
  return response
@@ -410,21 +489,25 @@ class CodeBase:
410
489
  model.delete_chat()
411
490
 
412
491
 
492
+
413
493
  def main():
414
494
  parser = argparse.ArgumentParser(description='Codebase management and search tool')
415
495
  parser.add_argument('--search', type=str, help='Search query to find similar code files')
416
- parser.add_argument('--top-k', type=int, default=5, help='Number of results to return (default: 5)')
496
+ parser.add_argument('--top-k', type=int, default=20, help='Number of results to return (default: 20)')
417
497
  parser.add_argument('--ask', type=str, help='Ask a question about the codebase')
498
+ parser.add_argument('--generate', action='store_true', help='Generate codebase index')
418
499
  args = parser.parse_args()
419
500
 
420
501
  current_dir = find_git_root()
421
502
  codebase = CodeBase(current_dir)
422
503
 
423
- try:
424
- codebase.generate_codebase()
425
- PrettyOutput.print("\nCodebase generation completed", output_type=OutputType.SUCCESS)
426
- except Exception as e:
427
- PrettyOutput.print(f"Error during codebase generation: {str(e)}", output_type=OutputType.ERROR)
504
+
505
+ if args.generate:
506
+ try:
507
+ codebase.generate_codebase()
508
+ PrettyOutput.print("\nCodebase generation completed", output_type=OutputType.SUCCESS)
509
+ except Exception as e:
510
+ PrettyOutput.print(f"Error during codebase generation: {str(e)}", output_type=OutputType.ERROR)
428
511
 
429
512
  if args.search:
430
513
  results = codebase.search_similar(args.search, args.top_k)
@@ -124,7 +124,7 @@ class JarvisCoder:
124
124
  return [patch.replace('<PATCH_START>', '').replace('<PATCH_END>', '').strip()
125
125
  for patch in patches if patch.strip()]
126
126
  except Exception as e:
127
- PrettyOutput.print(f"解析patch失败: {str(e)}", OutputType.ERROR)
127
+ PrettyOutput.print(f"解析patch失败: {str(e)}", OutputType.WARNING)
128
128
  return []
129
129
 
130
130
  def _make_patch(self, related_files: List[Dict], feature: str) -> List[str]:
@@ -138,20 +138,31 @@ class JarvisCoder:
138
138
  要替换的内容
139
139
  =======
140
140
  新的内容
141
- <<<<<<
141
+ >>>>>>
142
142
  <PATCH_END>
143
143
 
144
- 2. 如果是新文件,格式如下:
144
+ 2. 如果是新文件或者替换整个文件内容,格式如下:
145
145
  <PATCH_START>
146
146
  >>>>>> path/to/new/file
147
147
  =======
148
148
  新文件的完整内容
149
- <<<<<<
149
+ >>>>>>
150
+ <PATCH_END>
151
+
152
+ 3. 如果要删除文件中的某一段,格式如下:
153
+ <PATCH_START>
154
+ >>>>>> path/to/file
155
+ 要删除的内容
156
+ =======
157
+ >>>>>>
150
158
  <PATCH_END>
151
159
 
152
160
  文件列表如下:
153
161
  """
154
162
  for i, file in enumerate(related_files):
163
+ if len(prompt) > 30 * 1024:
164
+ PrettyOutput.print(f'避免上下文超限,丢弃低相关度文件:{file["file_path"]}', OutputType.WARNING)
165
+ continue
155
166
  prompt += f"""{i}. {file["file_path"]}\n"""
156
167
  prompt += f"""文件内容:\n"""
157
168
  prompt += f"<FILE_CONTENT_START>\n"
@@ -177,7 +188,7 @@ class JarvisCoder:
177
188
  return [patch.replace('<PATCH_START>', '').replace('<PATCH_END>', '').strip()
178
189
  for patch in patches if patch.strip()]
179
190
  except Exception as e:
180
- PrettyOutput.print(f"解析patch失败: {str(e)}", OutputType.ERROR)
191
+ PrettyOutput.print(f"解析patch失败: {str(e)}", OutputType.WARNING)
181
192
  return []
182
193
 
183
194
  def _apply_patch(self, related_files: List[Dict], patches: List[str]) -> Tuple[bool, str]:
@@ -216,7 +227,7 @@ class JarvisCoder:
216
227
  return False, "\n".join(error_info)
217
228
 
218
229
  old_content = parts[0]
219
- new_content = parts[1].split("<<<<<<")[0]
230
+ new_content = parts[1].split(">>>>>>")[0]
220
231
 
221
232
  # 处理新文件
222
233
  if not old_content:
@@ -297,17 +308,37 @@ class JarvisCoder:
297
308
 
298
309
 
299
310
 
311
+
300
312
  def _prepare_execution(self) -> None:
301
313
  """准备执行环境"""
302
314
  self.main_model = self._new_model()
303
- self._codebase.generate_codebase()
315
+
316
+
317
+ # 询问用户是否更新索引数据库
318
+ while True:
319
+ answer = get_multiline_input("是否要更新代码库索引数据库?(y/n)").strip().lower()
320
+ if answer == 'y':
321
+ PrettyOutput.print("正在更新代码库索引数据库...", OutputType.PROGRESS)
322
+ self._codebase.generate_codebase()
323
+ break
324
+ elif answer == 'n' or not answer:
325
+ PrettyOutput.print("跳过代码库索引数据库更新", OutputType.INFO)
326
+ break
327
+ else:
328
+ PrettyOutput.print("请输入 y 或 n", OutputType.WARNING)
329
+
304
330
 
305
331
  def _load_related_files(self, feature: str) -> List[Dict]:
306
332
  """加载相关文件内容"""
307
333
  ret = []
308
- related_files = self._codebase.search_similar(feature, top_k=5)
334
+ # 确保索引数据库已生成
335
+ if not self._codebase.is_index_generated():
336
+ PrettyOutput.print("检测到索引数据库未生成,正在生成...", OutputType.WARNING)
337
+ self._codebase.generate_codebase()
338
+
339
+ related_files = self._codebase.search_similar(feature)
309
340
  for file, score, _ in related_files:
310
- PrettyOutput.print(f"相关文件: {file} 相关度: {score:.3f}", OutputType.INFO)
341
+ PrettyOutput.print(f"相关文件: {file} 相关度: {score:.3f}", OutputType.SUCCESS)
311
342
  with open(file, "r", encoding="utf-8") as f:
312
343
  content = f.read()
313
344
  ret.append({"file_path": file, "file_content": content})
@@ -438,7 +469,7 @@ def main():
438
469
  PrettyOutput.print(result["stdout"], OutputType.SUCCESS)
439
470
  else:
440
471
  if result["stderr"]:
441
- PrettyOutput.print(result["stderr"], OutputType.ERROR)
472
+ PrettyOutput.print(result["stderr"], OutputType.WARNING)
442
473
  if result["error"]:
443
474
  PrettyOutput.print(f"错误类型: {type(result['error']).__name__}", OutputType.WARNING)
444
475
 
@@ -121,7 +121,7 @@ class PlatformRegistry:
121
121
  # 检查平台实现
122
122
  if not PlatformRegistry.check_platform_implementation(obj):
123
123
  continue
124
-
124
+ PrettyOutput.print(f"从 {os.path.join(directory, filename)} 加载平台:{obj.platform_name}", OutputType.SUCCESS)
125
125
  platforms[obj.platform_name] = obj
126
126
  break
127
127
  except Exception as e:
@@ -45,8 +45,11 @@ class CodebaseQATool:
45
45
  "stderr": "错误:当前目录不在Git仓库中",
46
46
  "error": "NotInGitRepository"
47
47
  }
48
+
48
49
  os.chdir(root_dir)
49
50
  codebase = CodeBase(root_dir)
51
+ # 生成索引
52
+ codebase.generate_codebase()
50
53
  # 执行问答
51
54
  response = codebase.ask_codebase(question, top_k)
52
55
  os.chdir(current_dir)
@@ -99,7 +99,7 @@ class ToolRegistry:
99
99
  parameters=tool_instance.parameters,
100
100
  func=tool_instance.execute
101
101
  )
102
- PrettyOutput.print(f"从 {file_path} 加载工具: {tool_instance.name}: {tool_instance.description}", OutputType.INFO)
102
+ PrettyOutput.print(f"从 {file_path} 加载工具: {tool_instance.name}: {tool_instance.description}", OutputType.SUCCESS)
103
103
  tool_found = True
104
104
  break
105
105
 
@@ -158,7 +158,7 @@ def get_multiline_input(tip: str) -> str:
158
158
  lines.append(line)
159
159
 
160
160
  except KeyboardInterrupt:
161
- PrettyOutput.print("\n输入已取消", OutputType.ERROR)
161
+ PrettyOutput.print("\n输入已取消", OutputType.INFO)
162
162
  return "__interrupt__"
163
163
 
164
164
  return "\n".join(lines)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.67
3
+ Version: 0.1.73
4
4
  Summary: Jarvis: An AI assistant that uses tools to interact with the system
5
5
  Home-page: https://github.com/skyfireitdiy/Jarvis
6
6
  Author: skyfire
@@ -44,9 +44,10 @@ Requires-Dist: colorama>=0.4.6
44
44
  Requires-Dist: prompt_toolkit>=3.0.0
45
45
  Requires-Dist: openai>=1.20.0
46
46
  Requires-Dist: playwright>=1.41.1
47
- Requires-Dist: numpy>=1.26.0
48
- Requires-Dist: faiss-cpu>=1.8.1
47
+ Requires-Dist: numpy>=1.24.0
48
+ Requires-Dist: faiss-cpu>=1.8.0
49
49
  Requires-Dist: sentence-transformers>=2.2.2
50
+ Requires-Dist: bs4>=0.0.1
50
51
  Provides-Extra: dev
51
52
  Requires-Dist: pytest; extra == "dev"
52
53
  Requires-Dist: black; extra == "dev"
@@ -9,6 +9,7 @@ src/jarvis/main.py
9
9
  src/jarvis/utils.py
10
10
  src/jarvis/jarvis_codebase/__init__.py
11
11
  src/jarvis/jarvis_codebase/main.py
12
+ src/jarvis/jarvis_coder/__init__.py
12
13
  src/jarvis/jarvis_coder/main.py
13
14
  src/jarvis/models/__init__.py
14
15
  src/jarvis/models/ai8.py
@@ -4,9 +4,10 @@ colorama>=0.4.6
4
4
  prompt_toolkit>=3.0.0
5
5
  openai>=1.20.0
6
6
  playwright>=1.41.1
7
- numpy>=1.26.0
8
- faiss-cpu>=1.8.1
7
+ numpy>=1.24.0
8
+ faiss-cpu>=1.8.0
9
9
  sentence-transformers>=2.2.2
10
+ bs4>=0.0.1
10
11
 
11
12
  [dev]
12
13
  pytest