jarvis-ai-assistant 0.1.111__py3-none-any.whl → 0.1.113__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 (46) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/agent.py +72 -41
  3. jarvis/jarvis_code_agent/code_agent.py +23 -5
  4. jarvis/jarvis_code_agent/file_select.py +16 -16
  5. jarvis/jarvis_code_agent/patch.py +17 -11
  6. jarvis/jarvis_code_agent/relevant_files.py +33 -40
  7. jarvis/jarvis_codebase/main.py +57 -48
  8. jarvis/jarvis_lsp/cpp.py +1 -1
  9. jarvis/jarvis_lsp/go.py +1 -1
  10. jarvis/jarvis_lsp/python.py +0 -2
  11. jarvis/jarvis_lsp/registry.py +13 -13
  12. jarvis/jarvis_lsp/rust.py +1 -1
  13. jarvis/jarvis_platform/ai8.py +14 -14
  14. jarvis/jarvis_platform/base.py +1 -1
  15. jarvis/jarvis_platform/kimi.py +17 -17
  16. jarvis/jarvis_platform/ollama.py +14 -14
  17. jarvis/jarvis_platform/openai.py +8 -8
  18. jarvis/jarvis_platform/oyi.py +19 -19
  19. jarvis/jarvis_platform/registry.py +6 -6
  20. jarvis/jarvis_platform_manager/main.py +17 -17
  21. jarvis/jarvis_rag/main.py +25 -25
  22. jarvis/jarvis_smart_shell/main.py +6 -6
  23. jarvis/jarvis_tools/ask_codebase.py +3 -3
  24. jarvis/jarvis_tools/ask_user.py +2 -2
  25. jarvis/jarvis_tools/create_code_agent.py +8 -8
  26. jarvis/jarvis_tools/create_sub_agent.py +2 -2
  27. jarvis/jarvis_tools/execute_shell.py +2 -2
  28. jarvis/jarvis_tools/file_operation.py +1 -1
  29. jarvis/jarvis_tools/git_commiter.py +8 -5
  30. jarvis/jarvis_tools/methodology.py +3 -3
  31. jarvis/jarvis_tools/rag.py +3 -3
  32. jarvis/jarvis_tools/read_code.py +1 -1
  33. jarvis/jarvis_tools/read_webpage.py +19 -6
  34. jarvis/jarvis_tools/registry.py +11 -11
  35. jarvis/jarvis_tools/search.py +88 -27
  36. jarvis/jarvis_tools/select_code_files.py +1 -1
  37. jarvis/jarvis_tools/tool_generator.py +182 -0
  38. jarvis/utils.py +69 -28
  39. jarvis_ai_assistant-0.1.113.dist-info/METADATA +460 -0
  40. jarvis_ai_assistant-0.1.113.dist-info/RECORD +64 -0
  41. jarvis_ai_assistant-0.1.111.dist-info/METADATA +0 -461
  42. jarvis_ai_assistant-0.1.111.dist-info/RECORD +0 -63
  43. {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/LICENSE +0 -0
  44. {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/WHEEL +0 -0
  45. {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/entry_points.txt +0 -0
  46. {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/top_level.txt +0 -0
@@ -8,60 +8,54 @@ from jarvis.jarvis_platform.registry import PlatformRegistry
8
8
  from jarvis.utils import OutputType, PrettyOutput
9
9
 
10
10
  def make_question(requirement: str) -> Optional[str]:
11
- """Generate structured questions to gather necessary information for the requirement.
12
-
13
- Args:
14
- requirement: The user's requirement description
15
-
16
- Returns:
17
- str: A formatted string containing relevant questions
18
- """
19
- prompt = f"""You are a helpful assistant that generates SPECIFIC questions in English for a code analysis team. The analysis team:
20
- - Has access to the codebase but NO CONTEXT about the requirement
21
- - Will search and analyze code based on your questions
22
- - Needs complete context to understand what to look for
11
+ """Generate structured questions to gather necessary information for the requirement."""
12
+ prompt = f"""You are a code analysis expert who helps developers understand existing system implementations. Generate specific questions to investigate:
13
+ - Current system implementations
14
+ - Existing interfaces and integration points
15
+ - Extension mechanisms and patterns
16
+ - Related components and their interactions
23
17
 
24
18
  Key Instructions:
25
- 1. Write questions in clear, professional English
26
- 2. Include necessary CONTEXT in each question
27
- 3. Be SPECIFIC about what needs to be found/analyzed
28
- 4. Provide enough background for someone with no prior knowledge
19
+ 1. Focus on understanding the EXISTING system
20
+ 2. Ask about interfaces, hooks, and extension points
21
+ 3. Investigate integration patterns and dependencies
22
+ 4. Explore current implementation details
29
23
 
30
24
  For example:
31
- BAD: "How is error handling implemented?"
32
- GOOD: "Given that we need to add retry logic to the file upload feature, how does the current error handling work in upload_handler.py, specifically around network failures and timeout scenarios?"
25
+ BAD: "How should we implement the new feature?"
26
+ GOOD: "What are the existing extension points in the authentication system that we can use to add the new OAuth provider? Specifically, how does AuthProvider interface work and where is it currently used?"
33
27
 
34
- Consider these aspects when forming questions:
28
+ Consider these investigation aspects:
35
29
 
36
- 1. Implementation Context:
37
- - "What is the current implementation of [specific feature]?"
38
- - "Which modules/classes handle [specific functionality]?"
39
- - "What is the existing workflow for [specific operation]?"
30
+ 1. System Architecture:
31
+ - "What are the existing interfaces/classes that handle [functionality]?"
32
+ - "How is [feature] currently integrated with other components?"
33
+ - "Where are the extension points for [system component]?"
40
34
 
41
- 2. Technical Investigation:
42
- - "How does the system currently handle [specific scenario]?"
43
- - "What patterns are used for [specific behavior]?"
44
- - "Where are the configuration settings for [specific feature]?"
35
+ 2. Implementation Details:
36
+ - "What is the current workflow for [operation] in the system?"
37
+ - "How does the system expose hooks/callbacks for [functionality]?"
38
+ - "Which interfaces/abstract classes are used for [feature] extensibility?"
45
39
 
46
- 3. Integration Details:
47
- - "Which components call or depend on [specific module]?"
48
- - "What is the data flow between [component A] and [component B]?"
49
- - "How are errors propagated from [specific component]?"
40
+ 3. Integration Patterns:
41
+ - "How do existing components integrate with [system part]?"
42
+ - "What are the current integration points for [feature]?"
43
+ - "How does the system handle extensions to [component]?"
50
44
 
51
- 4. Requirements Context:
52
- - "Given [specific requirement], what are the current limitations?"
53
- - "For [specific change], what validation rules apply?"
54
- - "In the context of [feature], what edge cases exist?"
45
+ 4. Extension Mechanisms:
46
+ - "What patterns are used for extending [functionality]?"
47
+ - "How do existing plugins/extensions connect to [system]?"
48
+ - "Where are the configuration points for [feature] customization?"
55
49
 
56
50
  User Requirement:
57
51
  {requirement}
58
52
 
59
53
  Output Format:
60
54
  <QUESTION>
61
- [Write 3-5 specific questions in English, ensuring each includes full context for someone with no prior knowledge of the requirement]
55
+ [Write 3-5 specific questions focusing on existing implementations and extension points. Each question should help understand how to integrate with or extend the current system]
62
56
  </QUESTION>
63
57
  """
64
- model = PlatformRegistry().get_normal_platform()
58
+ model = PlatformRegistry().get_thinking_platform()
65
59
  response = model.chat_until_success(prompt)
66
60
  response = re.search(r'<QUESTION>(.*?)</QUESTION>', response, re.DOTALL)
67
61
  if response is None:
@@ -71,16 +65,15 @@ Output Format:
71
65
 
72
66
  def find_relevant_information(user_input: str, root_dir: str) -> Tuple[List[Dict[str, str]], str]:
73
67
  try:
74
- PrettyOutput.print("Find files from codebase...", OutputType.INFO)
68
+ PrettyOutput.print("从代码库中查找文件...", OutputType.INFO)
75
69
  codebase = CodeBase(root_dir)
76
70
  question = make_question(user_input)
77
71
  if question is None:
78
72
  return [], ""
79
73
  files_from_codebase, infomation = codebase.ask_codebase(question)
80
- PrettyOutput.print("Find files by agent...", OutputType.INFO)
81
74
 
82
75
  selected_files = select_files(files_from_codebase, os.getcwd())
83
76
  return selected_files, infomation
84
77
  except Exception:
85
- PrettyOutput.print("Failed to find relevant files", OutputType.ERROR)
78
+ PrettyOutput.print("查找相关文件失败", OutputType.ERROR)
86
79
  return [], ""
@@ -37,9 +37,9 @@ class CodeBase:
37
37
  self.embedding_model.encode([test_text],
38
38
  convert_to_tensor=True,
39
39
  normalize_embeddings=True)
40
- PrettyOutput.print("Model loaded successfully", output_type=OutputType.SUCCESS)
40
+ PrettyOutput.print("模型加载成功", output_type=OutputType.SUCCESS)
41
41
  except Exception as e:
42
- PrettyOutput.print(f"Failed to load model: {str(e)}", output_type=OutputType.ERROR)
42
+ PrettyOutput.print(f"加载模型失败: {str(e)}", output_type=OutputType.ERROR)
43
43
  raise
44
44
 
45
45
  self.vector_dim = self.embedding_model.get_sentence_embedding_dimension()
@@ -71,7 +71,7 @@ class CodeBase:
71
71
  if self.thread_count > 1:
72
72
  model.set_suppress_output(True)
73
73
  else:
74
- PrettyOutput.print(f"Make description for {file_path} ...", output_type=OutputType.PROGRESS)
74
+ PrettyOutput.print(f" {file_path} 生成描述 ...", output_type=OutputType.PROGRESS)
75
75
  prompt = f"""Please analyze the following code file and generate a detailed description. The description should include:
76
76
  1. Overall file functionality description
77
77
  2. description for each global variable, function, type definition, class, method, and other code elements
@@ -129,7 +129,7 @@ Code content:
129
129
  self.file_paths.append(file_path)
130
130
  vectors.append(cache_data["vector"])
131
131
  except Exception as e:
132
- PrettyOutput.print(f"Failed to load cache file {cache_file}: {str(e)}",
132
+ PrettyOutput.print(f"加载缓存文件 {cache_file} 失败: {str(e)}",
133
133
  output_type=OutputType.WARNING)
134
134
  continue
135
135
 
@@ -142,14 +142,14 @@ Code content:
142
142
  self.index = faiss.IndexIDMap(hnsw_index)
143
143
  self.index.add_with_ids(vectors_array, np.array(range(len(vectors)))) # type: ignore
144
144
 
145
- PrettyOutput.print(f"Loaded {len(self.vector_cache)} vector cache and rebuilt index",
145
+ PrettyOutput.print(f"加载 {len(self.vector_cache)} 个向量缓存并重建索引",
146
146
  output_type=OutputType.INFO)
147
147
  else:
148
148
  self.index = None
149
- PrettyOutput.print("No valid cache files found", output_type=OutputType.WARNING)
149
+ PrettyOutput.print("没有找到有效的缓存文件", output_type=OutputType.WARNING)
150
150
 
151
151
  except Exception as e:
152
- PrettyOutput.print(f"Failed to load cache directory: {str(e)}",
152
+ PrettyOutput.print(f"加载缓存目录失败: {str(e)}",
153
153
  output_type=OutputType.WARNING)
154
154
  self.vector_cache = {}
155
155
  self.file_paths = []
@@ -161,7 +161,7 @@ Code content:
161
161
  with open(file_path, "rb") as f:
162
162
  file_md5 = hashlib.md5(f.read()).hexdigest()
163
163
  except Exception as e:
164
- PrettyOutput.print(f"Failed to calculate MD5 for {file_path}: {str(e)}",
164
+ PrettyOutput.print(f"计算 {file_path} 的MD5失败: {str(e)}",
165
165
  output_type=OutputType.ERROR)
166
166
  file_md5 = ""
167
167
 
@@ -182,7 +182,7 @@ Code content:
182
182
  with lzma.open(cache_path, 'wb') as f:
183
183
  pickle.dump(cache_data, f, protocol=pickle.HIGHEST_PROTOCOL)
184
184
  except Exception as e:
185
- PrettyOutput.print(f"Failed to save cache for {file_path}: {str(e)}",
185
+ PrettyOutput.print(f"保存 {file_path} 的缓存失败: {str(e)}",
186
186
  output_type=OutputType.ERROR)
187
187
 
188
188
  def get_cached_vector(self, file_path: str, description: str) -> Optional[np.ndarray]:
@@ -195,7 +195,7 @@ Code content:
195
195
  with open(file_path, "rb") as f:
196
196
  current_md5 = hashlib.md5(f.read()).hexdigest()
197
197
  except Exception as e:
198
- PrettyOutput.print(f"Failed to calculate MD5 for {file_path}: {str(e)}",
198
+ PrettyOutput.print(f"计算 {file_path} 的MD5失败: {str(e)}",
199
199
  output_type=OutputType.ERROR)
200
200
  return None
201
201
 
@@ -232,7 +232,7 @@ Content: {content}
232
232
  self.cache_vector(file_path, vector, description)
233
233
  return vector
234
234
  except Exception as e:
235
- PrettyOutput.print(f"Error vectorizing file {file_path}: {str(e)}",
235
+ PrettyOutput.print(f"向量化 {file_path} 失败: {str(e)}",
236
236
  output_type=OutputType.ERROR)
237
237
  return np.zeros(self.vector_dim, dtype=np.float32) # type: ignore
238
238
 
@@ -257,7 +257,7 @@ Content: {content}
257
257
  return bool(files_to_delete)
258
258
 
259
259
  except Exception as e:
260
- PrettyOutput.print(f"Failed to clean cache: {str(e)}",
260
+ PrettyOutput.print(f"清理缓存失败: {str(e)}",
261
261
  output_type=OutputType.ERROR)
262
262
  return False
263
263
 
@@ -293,7 +293,7 @@ Content: {content}
293
293
  return file_path
294
294
 
295
295
  except Exception as e:
296
- PrettyOutput.print(f"Failed to process file {file_path}: {str(e)}",
296
+ PrettyOutput.print(f"处理 {file_path} 失败: {str(e)}",
297
297
  output_type=OutputType.ERROR)
298
298
  return None
299
299
 
@@ -318,13 +318,13 @@ Content: {content}
318
318
 
319
319
  for i, (file_path, data) in enumerate(self.vector_cache.items()):
320
320
  if "vector" not in data:
321
- PrettyOutput.print(f"Invalid cache data for {file_path}: missing vector",
321
+ PrettyOutput.print(f"无效的缓存数据 {file_path}: 缺少向量",
322
322
  output_type=OutputType.WARNING)
323
323
  continue
324
324
 
325
325
  vector = data["vector"]
326
326
  if not isinstance(vector, np.ndarray):
327
- PrettyOutput.print(f"Invalid vector type for {file_path}: {type(vector)}",
327
+ PrettyOutput.print(f"无效的向量类型 {file_path}: {type(vector)}",
328
328
  output_type=OutputType.WARNING)
329
329
  continue
330
330
 
@@ -335,26 +335,26 @@ Content: {content}
335
335
  if vectors:
336
336
  vectors = np.vstack(vectors)
337
337
  if len(vectors) != len(ids):
338
- PrettyOutput.print(f"Vector count mismatch: {len(vectors)} vectors vs {len(ids)} ids",
338
+ PrettyOutput.print(f"向量数量不匹配: {len(vectors)} 个向量 vs {len(ids)} 个ID",
339
339
  output_type=OutputType.ERROR)
340
340
  self.index = None
341
341
  return
342
342
 
343
343
  try:
344
344
  self.index.add_with_ids(vectors, np.array(ids)) # type: ignore
345
- PrettyOutput.print(f"Successfully built index with {len(vectors)} vectors",
345
+ PrettyOutput.print(f"成功构建包含 {len(vectors)} 个向量的索引",
346
346
  output_type=OutputType.SUCCESS)
347
347
  except Exception as e:
348
- PrettyOutput.print(f"Failed to add vectors to index: {str(e)}",
348
+ PrettyOutput.print(f"添加向量到索引失败: {str(e)}",
349
349
  output_type=OutputType.ERROR)
350
350
  self.index = None
351
351
  else:
352
- PrettyOutput.print("No valid vectors found, index not built",
352
+ PrettyOutput.print("没有找到有效的向量, 索引未构建",
353
353
  output_type=OutputType.WARNING)
354
354
  self.index = None
355
355
 
356
356
  except Exception as e:
357
- PrettyOutput.print(f"Failed to build index: {str(e)}",
357
+ PrettyOutput.print(f"构建索引失败: {str(e)}",
358
358
  output_type=OutputType.ERROR)
359
359
  self.index = None
360
360
 
@@ -379,20 +379,20 @@ Content: {content}
379
379
  try:
380
380
  os.remove(cache_path)
381
381
  except Exception as e:
382
- PrettyOutput.print(f"Failed to delete cache file for {cached_file}: {str(e)}",
382
+ PrettyOutput.print(f"删除缓存文件 {cached_file} 失败: {str(e)}",
383
383
  output_type=OutputType.WARNING)
384
384
 
385
385
  if files_to_delete:
386
386
  for file_path in files_to_delete:
387
387
  del self.vector_cache[file_path]
388
- PrettyOutput.print(f"Cleaned cache for {len(files_to_delete)} non-existent files",
388
+ PrettyOutput.print(f"清理了 {len(files_to_delete)} 个不存在的文件的缓存",
389
389
  output_type=OutputType.INFO)
390
390
 
391
391
  # Update the git file list
392
392
  self.git_file_list = self.get_git_file_list()
393
393
 
394
394
  # Check file changes
395
- PrettyOutput.print("Check file changes...", output_type=OutputType.INFO)
395
+ PrettyOutput.print("检查文件变化...", output_type=OutputType.INFO)
396
396
  changes_detected = False
397
397
  new_files = []
398
398
  modified_files = []
@@ -424,36 +424,36 @@ Content: {content}
424
424
  modified_files.append(file_path)
425
425
  changes_detected = True
426
426
  except Exception as e:
427
- PrettyOutput.print(f"Failed to check file {file_path}: {str(e)}",
427
+ PrettyOutput.print(f"检查 {file_path} 失败: {str(e)}",
428
428
  output_type=OutputType.ERROR)
429
429
  progress.advance(task)
430
430
 
431
431
  # If changes are detected, display changes and ask the user
432
432
  if changes_detected:
433
- output_lines = ["Detected the following changes:"]
433
+ output_lines = ["检测到以下变化:"]
434
434
  if new_files:
435
- output_lines.append("New files:")
435
+ output_lines.append("新文件:")
436
436
  output_lines.extend(f" {f}" for f in new_files)
437
437
  if modified_files:
438
- output_lines.append("Modified files:")
438
+ output_lines.append("修改的文件:")
439
439
  output_lines.extend(f" {f}" for f in modified_files)
440
440
  if deleted_files:
441
- output_lines.append("Deleted files:")
441
+ output_lines.append("删除的文件:")
442
442
  output_lines.extend(f" {f}" for f in deleted_files)
443
443
 
444
444
  PrettyOutput.print("\n".join(output_lines), output_type=OutputType.WARNING)
445
445
 
446
446
  # If force is True, continue directly
447
447
  if not force:
448
- if not user_confirm("Rebuild the index?", False):
449
- PrettyOutput.print("Cancel rebuilding the index", output_type=OutputType.INFO)
448
+ if not user_confirm("重建索引?", False):
449
+ PrettyOutput.print("取消重建索引", output_type=OutputType.INFO)
450
450
  return
451
451
 
452
452
  # Clean deleted files
453
453
  for file_path in files_to_delete:
454
454
  del self.vector_cache[file_path]
455
455
  if files_to_delete:
456
- PrettyOutput.print(f"Cleaned the cache of {len(files_to_delete)} files",
456
+ PrettyOutput.print(f"清理了 {len(files_to_delete)} 个文件的缓存",
457
457
  output_type=OutputType.INFO)
458
458
 
459
459
  # Process new and modified files
@@ -482,19 +482,19 @@ Content: {content}
482
482
  pbar.update(1)
483
483
 
484
484
  if processed_files:
485
- PrettyOutput.print("Rebuilding the vector database...", output_type=OutputType.INFO)
485
+ PrettyOutput.print("重建向量数据库...", output_type=OutputType.INFO)
486
486
  self.gen_vector_db_from_cache()
487
- PrettyOutput.print(f"Successfully generated the index for {len(processed_files)} files",
487
+ PrettyOutput.print(f"成功生成了 {len(processed_files)} 个文件的索引",
488
488
  output_type=OutputType.SUCCESS)
489
489
  else:
490
- PrettyOutput.print("No file changes detected, no need to rebuild the index", output_type=OutputType.INFO)
490
+ PrettyOutput.print("没有检测到文件变化, 不需要重建索引", output_type=OutputType.INFO)
491
491
 
492
492
  except Exception as e:
493
493
  # Try to save the cache when an exception occurs
494
494
  try:
495
495
  self._load_all_cache()
496
496
  except Exception as save_error:
497
- PrettyOutput.print(f"Failed to save cache: {str(save_error)}",
497
+ PrettyOutput.print(f"保存缓存失败: {str(save_error)}",
498
498
  output_type=OutputType.ERROR)
499
499
  raise e # Re-raise the original exception
500
500
 
@@ -574,7 +574,7 @@ Content: {content}
574
574
  current_token_count += tokens_count
575
575
 
576
576
  except Exception as e:
577
- PrettyOutput.print(f"Failed to read file {path}: {str(e)}", OutputType.ERROR)
577
+ PrettyOutput.print(f"读取 {path} 失败: {str(e)}", OutputType.ERROR)
578
578
  continue
579
579
 
580
580
  # Process final batch
@@ -586,7 +586,7 @@ Content: {content}
586
586
  return all_selected_files
587
587
 
588
588
  except Exception as e:
589
- PrettyOutput.print(f"Failed to pick: {str(e)}", OutputType.ERROR)
589
+ PrettyOutput.print(f"选择失败: {str(e)}", OutputType.ERROR)
590
590
  return [{"file": f, "reason": "" } for f in initial_results]
591
591
 
592
592
  def _process_batch(self, query: str, files_info: List[str]) -> List[Dict[str, str]]:
@@ -639,7 +639,7 @@ Important:
639
639
  selected_files = yaml.safe_load(files_match.group(1))
640
640
  return selected_files if selected_files else []
641
641
  except Exception as e:
642
- PrettyOutput.print(f"Failed to parse response: {str(e)}", OutputType.ERROR)
642
+ PrettyOutput.print(f"解析响应失败: {str(e)}", OutputType.ERROR)
643
643
  return []
644
644
 
645
645
  def _generate_query_variants(self, query: str) -> List[str]:
@@ -687,7 +687,7 @@ Please provide 10 search-optimized expressions in the specified format.
687
687
  try:
688
688
  variants = yaml.safe_load(question_match.group(1))
689
689
  except Exception as e:
690
- PrettyOutput.print(f"Failed to parse variants: {str(e)}", OutputType.ERROR)
690
+ PrettyOutput.print(f"解析变体失败: {str(e)}", OutputType.ERROR)
691
691
 
692
692
  # Add original query
693
693
  variants.append(query)
@@ -776,7 +776,7 @@ Please provide 10 search-optimized expressions in the specified format.
776
776
  return results
777
777
 
778
778
  except Exception as e:
779
- PrettyOutput.print(f"Failed to search: {str(e)}", output_type=OutputType.ERROR)
779
+ PrettyOutput.print(f"搜索失败: {str(e)}", output_type=OutputType.ERROR)
780
780
  return []
781
781
 
782
782
  def ask_codebase(self, query: str, top_k: int=20) -> Tuple[List[Dict[str, str]], str]:
@@ -784,7 +784,7 @@ Please provide 10 search-optimized expressions in the specified format.
784
784
  files_from_codebase = self.search_similar(query, top_k)
785
785
 
786
786
  if not files_from_codebase:
787
- PrettyOutput.print("No related files found", output_type=OutputType.WARNING)
787
+ PrettyOutput.print("没有找到相关文件", output_type=OutputType.WARNING)
788
788
  return [],""
789
789
 
790
790
  # Build enhanced prompt
@@ -817,7 +817,7 @@ Content:
817
817
  """
818
818
  if current_count + get_context_token_count(file_content) > available_count:
819
819
  PrettyOutput.print(
820
- "Due to context length limit, some files were omitted",
820
+ "由于上下文长度限制, 一些文件被省略",
821
821
  output_type=OutputType.WARNING
822
822
  )
823
823
  break
@@ -826,11 +826,20 @@ Content:
826
826
  current_count += get_context_token_count(file_content)
827
827
 
828
828
  except Exception as e:
829
- PrettyOutput.print(f"Failed to read file {path}: {str(e)}",
829
+ PrettyOutput.print(f"读取 {path} 失败: {str(e)}",
830
830
  output_type=OutputType.ERROR)
831
831
  continue
832
832
 
833
833
  model = PlatformRegistry.get_global_platform_registry().get_thinking_platform()
834
+
835
+ prompt += """
836
+ Output Format:
837
+ - question: the question to answer
838
+ answer: the answer to the question
839
+ - question: the question to answer
840
+ answer: the answer to the question
841
+ """
842
+
834
843
  return files_from_codebase, model.chat_until_success(prompt)
835
844
 
836
845
  def is_index_generated(self) -> bool:
@@ -871,7 +880,7 @@ Content:
871
880
  return True
872
881
 
873
882
  except Exception as e:
874
- PrettyOutput.print(f"Error checking index status: {str(e)}",
883
+ PrettyOutput.print(f"检查索引状态失败: {str(e)}",
875
884
  output_type=OutputType.ERROR)
876
885
  return False
877
886
 
@@ -916,17 +925,17 @@ def main():
916
925
  if args.command == 'generate':
917
926
  try:
918
927
  codebase.generate_codebase(force=args.force)
919
- PrettyOutput.print("Codebase generation completed", output_type=OutputType.SUCCESS)
928
+ PrettyOutput.print("代码库生成完成", output_type=OutputType.SUCCESS)
920
929
  except Exception as e:
921
- PrettyOutput.print(f"Error during codebase generation: {str(e)}", output_type=OutputType.ERROR)
930
+ PrettyOutput.print(f"代码库生成失败: {str(e)}", output_type=OutputType.ERROR)
922
931
 
923
932
  elif args.command == 'search':
924
933
  results = codebase.search_similar(args.query, args.top_k)
925
934
  if not results:
926
- PrettyOutput.print("No similar files found", output_type=OutputType.WARNING)
935
+ PrettyOutput.print("没有找到相似的文件", output_type=OutputType.WARNING)
927
936
  return
928
937
 
929
- output = "Search Results:\n"
938
+ output = "搜索结果:\n"
930
939
  for path in results:
931
940
  output += f"""- {path}\n"""
932
941
  PrettyOutput.print(output, output_type=OutputType.INFO, lang="markdown")
jarvis/jarvis_lsp/cpp.py CHANGED
@@ -41,7 +41,7 @@ class CPPLSP(BaseLSP):
41
41
 
42
42
  return True
43
43
  except Exception as e:
44
- PrettyOutput.print(f"C++ LSP initialization failed: {str(e)}", OutputType.ERROR)
44
+ PrettyOutput.print(f"C++ LSP 初始化失败: {str(e)}", OutputType.ERROR)
45
45
  return False
46
46
 
47
47
  def _send_request(self, method: str, params: Dict) -> Optional[Dict]:
jarvis/jarvis_lsp/go.py CHANGED
@@ -47,7 +47,7 @@ class GoLSP(BaseLSP):
47
47
 
48
48
  return True
49
49
  except Exception as e:
50
- PrettyOutput.print(f"Go LSP initialization failed: {str(e)}", OutputType.ERROR)
50
+ PrettyOutput.print(f"Go LSP 初始化失败: {str(e)}", OutputType.ERROR)
51
51
  return False
52
52
 
53
53
  def _send_request(self, method: str, params: Dict) -> Optional[Dict]:
@@ -1,8 +1,6 @@
1
- import os
2
1
  from typing import List, Dict, Optional, Tuple, Any
3
2
  import jedi
4
3
  from jarvis.jarvis_lsp.base import BaseLSP
5
- from jarvis.utils import PrettyOutput, OutputType
6
4
 
7
5
  class PythonLSP(BaseLSP):
8
6
  """Python LSP implementation using jedi."""
@@ -33,7 +33,7 @@ class LSPRegistry:
33
33
  with open(os.path.join(user_lsp_dir, "__init__.py"), "w") as f:
34
34
  pass
35
35
  except Exception as e:
36
- PrettyOutput.print(f"Create LSP directory failed: {str(e)}", OutputType.ERROR)
36
+ PrettyOutput.print(f"创建 LSP 目录失败: {str(e)}", OutputType.ERROR)
37
37
  return ""
38
38
  return user_lsp_dir
39
39
 
@@ -72,7 +72,7 @@ class LSPRegistry:
72
72
  lsp_servers = {}
73
73
 
74
74
  if not os.path.exists(directory):
75
- PrettyOutput.print(f"LSP directory does not exist: {directory}", OutputType.ERROR)
75
+ PrettyOutput.print(f"LSP 目录不存在: {directory}", OutputType.ERROR)
76
76
  return lsp_servers
77
77
 
78
78
  package_name = None
@@ -104,7 +104,7 @@ class LSPRegistry:
104
104
  lsp_servers[obj.language] = obj
105
105
  break
106
106
  except Exception as e:
107
- PrettyOutput.print(f"Load LSP {module_name} failed: {str(e)}", OutputType.ERROR)
107
+ PrettyOutput.print(f"加载 LSP {module_name} 失败: {str(e)}", OutputType.ERROR)
108
108
 
109
109
  return lsp_servers
110
110
 
@@ -138,14 +138,14 @@ class LSPRegistry:
138
138
  def create_lsp(self, language: str) -> Optional[BaseLSP]:
139
139
  """Create LSP instance for specified language."""
140
140
  if language not in self.lsp_servers:
141
- PrettyOutput.print(f"LSP not found for language: {language}", OutputType.ERROR)
141
+ PrettyOutput.print(f"没有找到 LSP 支持的语言: {language}", OutputType.ERROR)
142
142
  return None
143
143
 
144
144
  try:
145
145
  lsp = self.lsp_servers[language]()
146
146
  return lsp
147
147
  except Exception as e:
148
- PrettyOutput.print(f"Create LSP failed: {str(e)}", OutputType.ERROR)
148
+ PrettyOutput.print(f"创建 LSP 失败: {str(e)}", OutputType.ERROR)
149
149
  return None
150
150
 
151
151
  def get_supported_languages(self) -> List[str]:
@@ -186,11 +186,11 @@ def main():
186
186
  lsp = registry.create_lsp(args.language)
187
187
 
188
188
  if not lsp:
189
- PrettyOutput.print(f"No LSP support for language: {args.language}", OutputType.ERROR)
189
+ PrettyOutput.print(f"没有 LSP 支持的语言: {args.language}", OutputType.ERROR)
190
190
  return 1
191
191
 
192
192
  if not lsp.initialize(os.path.dirname(os.path.abspath(args.file))):
193
- PrettyOutput.print("LSP initialization failed", OutputType.ERROR)
193
+ PrettyOutput.print("LSP 初始化失败", OutputType.ERROR)
194
194
  return 1
195
195
 
196
196
  try:
@@ -204,26 +204,26 @@ def main():
204
204
  diagnostics = lsp.get_diagnostics(args.file)
205
205
  for diag in diagnostics:
206
206
  severity = ['Error', 'Warning', 'Info', 'Hint'][diag['severity'] - 1]
207
- print(f"{severity} at {diag['range']['start']['line']}:{diag['range']['start']['character']}: {diag['message']}")
207
+ PrettyOutput.print(f"{severity} {diag['range']['start']['line']}:{diag['range']['start']['character']}: {diag['message']}", OutputType.INFO)
208
208
 
209
209
  elif args.action in ('references', 'definition'):
210
210
  if args.line is None or args.character is None:
211
- PrettyOutput.print("Line and character position required for references/definition", OutputType.ERROR)
211
+ PrettyOutput.print("需要行和字符位置用于 references/definition", OutputType.ERROR)
212
212
  return 1
213
213
 
214
214
  if args.action == 'references':
215
215
  refs = lsp.find_references(args.file, (args.line, args.character))
216
216
  for ref in refs:
217
- print(f"Reference in {ref['uri']} at {ref['range']['start']['line']}:{ref['range']['start']['character']}\nLine: {LSPRegistry.get_line_at_position(ref['uri'], ref['range']['start']['line'])}")
217
+ PrettyOutput.print(f"引用在 {ref['uri']} {ref['range']['start']['line']}:{ref['range']['start']['character']}\n行: {LSPRegistry.get_line_at_position(ref['uri'], ref['range']['start']['line'])}", OutputType.INFO)
218
218
  else:
219
219
  defn = lsp.find_definition(args.file, (args.line, args.character))
220
220
  if defn:
221
- print(f"Definition in {defn['uri']} at {defn['range']['start']['line']}:{defn['range']['start']['character']}\nLine: {LSPRegistry.get_line_at_position(defn['uri'], defn['range']['start']['line'])}")
221
+ PrettyOutput.print(f"定义在 {defn['uri']} {defn['range']['start']['line']}:{defn['range']['start']['character']}\n行: {LSPRegistry.get_line_at_position(defn['uri'], defn['range']['start']['line'])}", OutputType.INFO)
222
222
  else:
223
- print("No definition found")
223
+ PrettyOutput.print("没有找到定义", OutputType.WARNING)
224
224
 
225
225
  except Exception as e:
226
- PrettyOutput.print(f"Error: {str(e)}", OutputType.ERROR)
226
+ PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
227
227
  return 1
228
228
  finally:
229
229
  lsp.shutdown()
jarvis/jarvis_lsp/rust.py CHANGED
@@ -49,7 +49,7 @@ class RustLSP(BaseLSP):
49
49
 
50
50
  return True
51
51
  except Exception as e:
52
- PrettyOutput.print(f"Rust LSP initialization failed: {str(e)}", OutputType.ERROR)
52
+ PrettyOutput.print(f"Rust LSP 初始化失败: {str(e)}", OutputType.ERROR)
53
53
  return False
54
54
 
55
55
  def _send_request(self, method: str, params: Dict) -> Optional[Dict]: