jarvis-ai-assistant 0.1.123__py3-none-any.whl → 0.1.125__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 (67) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +19 -21
  3. jarvis/jarvis_code_agent/code_agent.py +205 -119
  4. jarvis/jarvis_code_agent/file_select.py +6 -105
  5. jarvis/jarvis_code_agent/patch.py +192 -259
  6. jarvis/jarvis_codebase/main.py +6 -2
  7. jarvis/jarvis_dev/main.py +6 -4
  8. jarvis/jarvis_git_squash/__init__.py +0 -0
  9. jarvis/jarvis_git_squash/main.py +81 -0
  10. jarvis/jarvis_lsp/cpp.py +1 -1
  11. jarvis/jarvis_lsp/go.py +1 -1
  12. jarvis/jarvis_lsp/registry.py +2 -2
  13. jarvis/jarvis_lsp/rust.py +1 -1
  14. jarvis/jarvis_multi_agent/__init__.py +1 -1
  15. jarvis/jarvis_platform/ai8.py +2 -1
  16. jarvis/jarvis_platform/base.py +20 -25
  17. jarvis/jarvis_platform/kimi.py +2 -3
  18. jarvis/jarvis_platform/ollama.py +3 -1
  19. jarvis/jarvis_platform/openai.py +1 -1
  20. jarvis/jarvis_platform/oyi.py +2 -1
  21. jarvis/jarvis_platform/registry.py +2 -1
  22. jarvis/jarvis_platform_manager/main.py +4 -6
  23. jarvis/jarvis_platform_manager/openai_test.py +0 -1
  24. jarvis/jarvis_rag/main.py +5 -2
  25. jarvis/jarvis_smart_shell/main.py +9 -4
  26. jarvis/jarvis_tools/ask_codebase.py +12 -7
  27. jarvis/jarvis_tools/ask_user.py +3 -2
  28. jarvis/jarvis_tools/base.py +21 -7
  29. jarvis/jarvis_tools/chdir.py +25 -1
  30. jarvis/jarvis_tools/code_review.py +13 -14
  31. jarvis/jarvis_tools/create_code_agent.py +4 -7
  32. jarvis/jarvis_tools/create_sub_agent.py +2 -2
  33. jarvis/jarvis_tools/execute_shell.py +3 -1
  34. jarvis/jarvis_tools/execute_shell_script.py +58 -0
  35. jarvis/jarvis_tools/file_operation.py +3 -2
  36. jarvis/jarvis_tools/git_commiter.py +26 -17
  37. jarvis/jarvis_tools/lsp_find_definition.py +1 -1
  38. jarvis/jarvis_tools/lsp_find_references.py +1 -1
  39. jarvis/jarvis_tools/lsp_get_diagnostics.py +19 -11
  40. jarvis/jarvis_tools/lsp_get_document_symbols.py +1 -1
  41. jarvis/jarvis_tools/lsp_prepare_rename.py +1 -1
  42. jarvis/jarvis_tools/lsp_validate_edit.py +1 -1
  43. jarvis/jarvis_tools/methodology.py +4 -1
  44. jarvis/jarvis_tools/rag.py +22 -15
  45. jarvis/jarvis_tools/read_code.py +4 -3
  46. jarvis/jarvis_tools/read_webpage.py +2 -1
  47. jarvis/jarvis_tools/registry.py +4 -1
  48. jarvis/jarvis_tools/{search.py → search_web.py} +5 -3
  49. jarvis/jarvis_tools/select_code_files.py +1 -1
  50. jarvis/jarvis_utils/__init__.py +19 -941
  51. jarvis/jarvis_utils/config.py +138 -0
  52. jarvis/jarvis_utils/embedding.py +201 -0
  53. jarvis/jarvis_utils/git_utils.py +120 -0
  54. jarvis/jarvis_utils/globals.py +82 -0
  55. jarvis/jarvis_utils/input.py +161 -0
  56. jarvis/jarvis_utils/methodology.py +128 -0
  57. jarvis/jarvis_utils/output.py +235 -0
  58. jarvis/jarvis_utils/utils.py +150 -0
  59. jarvis_ai_assistant-0.1.125.dist-info/METADATA +291 -0
  60. jarvis_ai_assistant-0.1.125.dist-info/RECORD +75 -0
  61. {jarvis_ai_assistant-0.1.123.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/WHEEL +1 -1
  62. {jarvis_ai_assistant-0.1.123.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/entry_points.txt +1 -0
  63. jarvis/jarvis_code_agent/relevant_files.py +0 -117
  64. jarvis_ai_assistant-0.1.123.dist-info/METADATA +0 -461
  65. jarvis_ai_assistant-0.1.123.dist-info/RECORD +0 -65
  66. {jarvis_ai_assistant-0.1.123.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/LICENSE +0 -0
  67. {jarvis_ai_assistant-0.1.123.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/top_level.txt +0 -0
@@ -5,7 +5,7 @@ import re
5
5
  import sys
6
6
  from typing import Dict, Type, Optional, List
7
7
  from jarvis.jarvis_lsp.base import BaseLSP
8
- from jarvis.jarvis_utils import PrettyOutput, OutputType
8
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
9
 
10
10
  REQUIRED_METHODS = [
11
11
  ('initialize', ['workspace_path']),
@@ -189,7 +189,7 @@ def main():
189
189
  PrettyOutput.print(f"没有 LSP 支持的语言: {args.language}", OutputType.WARNING)
190
190
  return 1
191
191
 
192
- if not lsp.initialize(os.path.dirname(os.path.abspath(args.file))):
192
+ if not lsp.initialize(os.path.abspath(os.getcwd())):
193
193
  PrettyOutput.print("LSP 初始化失败", OutputType.WARNING)
194
194
  return 1
195
195
 
jarvis/jarvis_lsp/rust.py CHANGED
@@ -4,7 +4,7 @@ import subprocess
4
4
  from typing import List, Dict, Optional, Tuple, Any
5
5
  import json
6
6
  from jarvis.jarvis_lsp.base import BaseLSP
7
- from jarvis.jarvis_utils import PrettyOutput, OutputType
7
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
8
8
 
9
9
  class RustLSP(BaseLSP):
10
10
  """Rust LSP implementation using rust-analyzer."""
@@ -5,7 +5,7 @@ import yaml
5
5
 
6
6
  from jarvis.jarvis_agent import Agent
7
7
  from jarvis.jarvis_agent.output_handler import OutputHandler
8
- from jarvis.jarvis_utils import OutputType, PrettyOutput
8
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
9
 
10
10
 
11
11
  class AgentConfig:
@@ -1,11 +1,12 @@
1
1
  import os
2
2
  from typing import Dict, List, Tuple
3
3
  from jarvis.jarvis_platform.base import BasePlatform
4
- from jarvis.jarvis_utils import PrettyOutput, OutputType
5
4
  import requests
6
5
  import json
7
6
  import base64
8
7
 
8
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
+
9
10
  class AI8Model(BasePlatform):
10
11
  """AI8 model implementation"""
11
12
 
@@ -1,10 +1,8 @@
1
1
  from abc import ABC, abstractmethod
2
2
  import re
3
3
  from typing import Dict, List, Tuple
4
-
5
- from jarvis.jarvis_utils import OutputType, PrettyOutput, while_success, while_true
6
- from yaspin import yaspin
7
- from yaspin.spinners import Spinners
4
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
5
+ from jarvis.jarvis_utils.utils import get_context_token_count, while_success, while_true
8
6
 
9
7
 
10
8
  class BasePlatform(ABC):
@@ -34,30 +32,27 @@ class BasePlatform(ABC):
34
32
  start_time = time.time()
35
33
  response = self.chat(message)
36
34
 
37
- # Calculate statistics
38
- if not self.suppress_output:
39
- end_time = time.time()
40
- duration = end_time - start_time
41
- char_count = len(response)
42
-
43
- # Calculate token count and tokens per second
44
- try:
45
- from jarvis.jarvis_utils import get_context_token_count
46
- token_count = get_context_token_count(response)
47
- tokens_per_second = token_count / duration if duration > 0 else 0
48
- except Exception as e:
49
- PrettyOutput.print(f"Tokenization failed: {str(e)}", OutputType.WARNING)
50
- token_count = 0
51
- tokens_per_second = 0
35
+ end_time = time.time()
36
+ duration = end_time - start_time
37
+ char_count = len(response)
38
+
39
+ # Calculate token count and tokens per second
40
+ try:
41
+ token_count = get_context_token_count(response)
42
+ tokens_per_second = token_count / duration if duration > 0 else 0
43
+ except Exception as e:
44
+ PrettyOutput.print(f"Tokenization failed: {str(e)}", OutputType.WARNING)
45
+ token_count = 0
46
+ tokens_per_second = 0
52
47
 
53
- # Print statistics
54
- PrettyOutput.print(
55
- f"对话完成 - 耗时: {duration:.2f}秒, 输出字符数: {char_count}, 输出Token数量: {token_count}, 每秒Token数量: {tokens_per_second:.2f}",
56
- OutputType.INFO,
57
- )
48
+ # Print statistics
49
+ PrettyOutput.print(
50
+ f"对话完成 - 耗时: {duration:.2f}秒, 输出字符数: {char_count}, 输出Token数量: {token_count}, 每秒Token数量: {tokens_per_second:.2f}",
51
+ OutputType.INFO,
52
+ )
58
53
 
59
54
  # Keep original think tag handling
60
- response = re.sub(r'<<think>>.*?</</think>>', '', response, flags=re.DOTALL)
55
+ response = re.sub(r'<think>.*?</think>', '', response, flags=re.DOTALL)
61
56
  return response
62
57
 
63
58
  return while_true(lambda: while_success(lambda: _chat(), 5), 5)
@@ -5,9 +5,8 @@ import os
5
5
  import mimetypes
6
6
  import time
7
7
  from jarvis.jarvis_platform.base import BasePlatform
8
- from jarvis.jarvis_utils import PrettyOutput, OutputType
9
- from jarvis.jarvis_utils import while_success
10
-
8
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
+ from jarvis.jarvis_utils.utils import while_success
11
10
  class KimiModel(BasePlatform):
12
11
  """Kimi model implementation"""
13
12
 
@@ -1,10 +1,12 @@
1
1
  import requests
2
2
  from typing import List, Dict, Tuple
3
3
  from jarvis.jarvis_platform.base import BasePlatform
4
- from jarvis.jarvis_utils import OutputType, PrettyOutput, get_single_line_input
5
4
  import os
6
5
  import json
7
6
 
7
+ from jarvis.jarvis_utils.input import get_single_line_input
8
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
+
8
10
  class OllamaPlatform(BasePlatform):
9
11
  """Ollama platform implementation"""
10
12
 
@@ -2,7 +2,7 @@ from typing import Dict, List, Tuple
2
2
  import os
3
3
  from openai import OpenAI
4
4
  from jarvis.jarvis_platform.base import BasePlatform
5
- from jarvis.jarvis_utils import PrettyOutput, OutputType
5
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
6
6
 
7
7
  class OpenAIModel(BasePlatform):
8
8
  platform_name = "openai"
@@ -2,10 +2,11 @@ import mimetypes
2
2
  import os
3
3
  from typing import Dict, List, Tuple
4
4
  from jarvis.jarvis_platform.base import BasePlatform
5
- from jarvis.jarvis_utils import PrettyOutput, OutputType
6
5
  import requests
7
6
  import json
8
7
 
8
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
+
9
10
  class OyiModel(BasePlatform):
10
11
  """Oyi model implementation"""
11
12
 
@@ -4,7 +4,8 @@ import os
4
4
  import sys
5
5
  from typing import Dict, Type, Optional, List
6
6
  from jarvis.jarvis_platform.base import BasePlatform
7
- from jarvis.jarvis_utils import PrettyOutput, OutputType, get_cheap_model_name, get_cheap_platform_name, get_codegen_model_name, get_codegen_platform_name, get_normal_model_name, get_normal_platform_name, get_thinking_model_name, get_thinking_platform_name
7
+ from jarvis.jarvis_utils.config import get_cheap_model_name, get_cheap_platform_name, get_codegen_model_name, get_codegen_platform_name, get_normal_model_name, get_normal_platform_name, get_thinking_model_name, get_thinking_platform_name
8
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
8
9
 
9
10
  REQUIRED_METHODS = [
10
11
  ('chat', ['message']), # 方法名和参数列表
@@ -1,18 +1,16 @@
1
1
  from jarvis.jarvis_platform.registry import PlatformRegistry
2
- from jarvis.jarvis_utils import PrettyOutput, OutputType, init_env, get_multiline_input
3
2
  import asyncio
4
3
  from fastapi import FastAPI, HTTPException
5
4
  from fastapi.responses import StreamingResponse
6
5
  from pydantic import BaseModel, Field
7
6
  from typing import List, Dict, Any, Optional
8
7
  import uvicorn
9
- import io
10
- from contextlib import redirect_stdout
11
- import json
12
- import os
13
- from datetime import datetime
14
8
  from fastapi.middleware.cors import CORSMiddleware
15
9
 
10
+ from jarvis.jarvis_utils.input import get_multiline_input
11
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
12
+ from jarvis.jarvis_utils.utils import init_env
13
+
16
14
  def list_platforms():
17
15
  """List all supported platforms and models"""
18
16
  registry = PlatformRegistry.get_global_platform_registry()
@@ -4,7 +4,6 @@ Test script for Jarvis OpenAI-compatible API service.
4
4
  """
5
5
 
6
6
  import argparse
7
- import os
8
7
  import sys
9
8
  from openai import OpenAI
10
9
 
jarvis/jarvis_rag/main.py CHANGED
@@ -3,8 +3,6 @@ import numpy as np
3
3
  import faiss
4
4
  from typing import List, Tuple, Optional, Dict
5
5
  import pickle
6
- from jarvis.jarvis_utils import OutputType, PrettyOutput, get_context_token_count, get_embedding, get_embedding_batch, get_file_md5, get_max_token_count, get_max_paragraph_length, get_min_paragraph_length, get_thread_count, init_gpu_config, load_embedding_model
7
- from jarvis.jarvis_utils import init_env
8
6
  from dataclasses import dataclass
9
7
  from tqdm import tqdm
10
8
  import fitz # PyMuPDF for PDF files
@@ -15,6 +13,11 @@ import lzma # 添加 lzma 导入
15
13
  from threading import Lock
16
14
  import hashlib
17
15
 
16
+ from jarvis.jarvis_utils.config import get_max_paragraph_length, get_max_token_count, get_min_paragraph_length, get_thread_count
17
+ from jarvis.jarvis_utils.embedding import get_context_token_count, get_embedding, get_embedding_batch, load_embedding_model
18
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
19
+ from jarvis.jarvis_utils.utils import get_file_md5, init_env, init_gpu_config
20
+
18
21
  @dataclass
19
22
  class Document:
20
23
  """Document class, for storing document content and metadata"""
@@ -4,11 +4,14 @@ import os
4
4
  import sys
5
5
  import readline
6
6
  from typing import Optional
7
- from yaspin import yaspin # type: ignore
8
- from yaspin.spinners import Spinners # type: ignore
7
+
8
+ from yaspin import yaspin
9
9
 
10
10
  from jarvis.jarvis_platform.registry import PlatformRegistry
11
- from jarvis.jarvis_utils import PrettyOutput, OutputType, get_multiline_input, get_shell_name, init_env
11
+ from jarvis.jarvis_utils.config import get_shell_name
12
+ from jarvis.jarvis_utils.input import get_multiline_input
13
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
14
+ from jarvis.jarvis_utils.utils import init_env
12
15
 
13
16
  def execute_command(command: str) -> None:
14
17
  """Show command and allow user to edit, then execute, Ctrl+C to cancel"""
@@ -95,7 +98,9 @@ Output: find . -name "*.py"
95
98
  prefix = f"Current path: {current_path}\n"
96
99
  prefix += f"Current shell: {shell}\n"
97
100
 
98
- result = model.chat_until_success(prefix + request)
101
+ with yaspin(text="正在生成命令...", color="cyan") as spinner:
102
+ result = model.chat_until_success(prefix + request)
103
+ spinner.ok("✅ 命令生成成功")
99
104
 
100
105
  # 提取命令
101
106
  if result and isinstance(result, str):
@@ -1,6 +1,8 @@
1
1
  from typing import Dict, Any
2
- from jarvis.jarvis_utils import OutputType, PrettyOutput, dont_use_local_model, find_git_root
3
2
  from jarvis.jarvis_codebase.main import CodeBase
3
+ from jarvis.jarvis_utils.config import dont_use_local_model
4
+ from jarvis.jarvis_utils.git_utils import find_git_root
5
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
4
6
 
5
7
  class AskCodebaseTool:
6
8
  """Tool for intelligent codebase querying and analysis using CodeBase"""
@@ -52,14 +54,20 @@ class AskCodebaseTool:
52
54
  codebase = CodeBase(git_root)
53
55
 
54
56
  # Use ask_codebase method
55
- _, response = codebase.ask_codebase(question, top_k)
56
-
57
+ files, response = codebase.ask_codebase(question, top_k)
58
+
59
+ # Print found files
60
+ if files:
61
+ output = "找到的相关文件:\n"
62
+ for file in files:
63
+ output += f"- {file['file']} ({file['reason']})\n"
64
+ PrettyOutput.print(output, OutputType.INFO, lang="markdown")
65
+
57
66
  return {
58
67
  "success": True,
59
68
  "stdout": response,
60
69
  "stderr": ""
61
70
  }
62
-
63
71
  except Exception as e:
64
72
  error_msg = f"分析代码库失败: {str(e)}"
65
73
  PrettyOutput.print(error_msg, OutputType.WARNING)
@@ -68,8 +76,6 @@ class AskCodebaseTool:
68
76
  "stdout": "",
69
77
  "stderr": error_msg
70
78
  }
71
-
72
-
73
79
  def main():
74
80
  """Command line interface for the tool"""
75
81
  import argparse
@@ -79,7 +85,6 @@ def main():
79
85
  parser.add_argument('--top-k', type=int, help='Number of files to analyze', default=20)
80
86
 
81
87
  args = parser.parse_args()
82
-
83
88
  tool = AskCodebaseTool()
84
89
  result = tool.execute({
85
90
  "question": args.question,
@@ -1,6 +1,7 @@
1
1
  from typing import Dict, Any
2
- from jarvis.jarvis_tools.base import Tool
3
- from jarvis.jarvis_utils import get_multiline_input, PrettyOutput, OutputType
2
+
3
+ from jarvis.jarvis_utils.input import get_multiline_input
4
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
4
5
 
5
6
  class AskUserTool:
6
7
  name="ask_user"
@@ -1,23 +1,37 @@
1
1
  from typing import Dict, Any, Callable
2
2
  import json
3
-
4
-
5
-
6
3
  class Tool:
4
+ """工具类,用于封装工具的基本信息和执行方法"""
5
+
7
6
  def __init__(self, name: str, description: str, parameters: Dict, func: Callable):
7
+ """
8
+ 初始化工具对象
9
+
10
+ Args:
11
+ name (str): 工具名称
12
+ description (str): 工具描述
13
+ parameters (Dict): 工具参数定义
14
+ func (Callable): 工具执行函数
15
+ """
8
16
  self.name = name
9
17
  self.description = description
10
18
  self.parameters = parameters
11
19
  self.func = func
12
-
13
20
  def to_dict(self) -> Dict:
14
- """Convert to tool format"""
21
+ """将工具对象转换为字典格式,主要用于序列化"""
15
22
  return {
16
23
  "name": self.name,
17
24
  "description": self.description,
18
25
  "parameters": json.dumps(self.parameters, ensure_ascii=False)
19
26
  }
20
-
21
27
  def execute(self, arguments: Dict) -> Dict[str, Any]:
22
- """Execute tool function"""
28
+ """
29
+ 执行工具函数
30
+
31
+ Args:
32
+ arguments (Dict): 工具执行所需的参数
33
+
34
+ Returns:
35
+ Dict[str, Any]: 工具执行结果
36
+ """
23
37
  return self.func(arguments)
@@ -1,6 +1,5 @@
1
1
  from typing import Dict, Any
2
2
  import os
3
- from jarvis.jarvis_utils import PrettyOutput, OutputType
4
3
 
5
4
  class ChdirTool:
6
5
  name = "chdir"
@@ -17,10 +16,31 @@ class ChdirTool:
17
16
  }
18
17
 
19
18
  def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
19
+ """Execute directory change operation with comprehensive error handling.
20
+
21
+ Args:
22
+ args: Dictionary containing 'path' key with target directory path
23
+
24
+ Returns:
25
+ Dictionary containing:
26
+ - success: Boolean indicating operation status
27
+ - stdout: Success message or empty string
28
+ - stderr: Error message or empty string
29
+
30
+ Raises:
31
+ Handles and returns appropriate error messages for:
32
+ - Non-existent paths
33
+ - Non-directory paths
34
+ - Permission errors
35
+ - Generic exceptions
36
+ """
37
+ # Main execution block with comprehensive error handling
20
38
  try:
39
+ # Normalize and expand the input path (handles ~ and relative paths)
21
40
  path = os.path.expanduser(args["path"].strip())
22
41
  path = os.path.abspath(path)
23
42
 
43
+ # Validate that the target path exists
24
44
  if not os.path.exists(path):
25
45
  return {
26
46
  "success": False,
@@ -28,6 +48,7 @@ class ChdirTool:
28
48
  "stderr": f"Directory does not exist: {path}"
29
49
  }
30
50
 
51
+ # Ensure the path points to a directory, not a file
31
52
  if not os.path.isdir(path):
32
53
  return {
33
54
  "success": False,
@@ -35,6 +56,7 @@ class ChdirTool:
35
56
  "stderr": f"The path is not a directory: {path}"
36
57
  }
37
58
 
59
+ # Capture current directory and attempt to change to new path
38
60
  old_path = os.getcwd()
39
61
  os.chdir(path)
40
62
 
@@ -44,12 +66,14 @@ class ChdirTool:
44
66
  "stderr": ""
45
67
  }
46
68
 
69
+ # Handle cases where user lacks directory access permissions
47
70
  except PermissionError:
48
71
  return {
49
72
  "success": False,
50
73
  "stdout": "",
51
74
  "stderr": f"No permission to access directory: {path}"
52
75
  }
76
+ # Catch-all for any other unexpected errors during directory change
53
77
  except Exception as e:
54
78
  return {
55
79
  "success": False,
@@ -1,12 +1,13 @@
1
- from typing import Dict, Any, List
1
+ from typing import Dict, Any
2
2
  import subprocess
3
- import yaml
4
3
  from jarvis.jarvis_platform.registry import PlatformRegistry
5
4
  from jarvis.jarvis_tools.registry import ToolRegistry
6
- from jarvis.jarvis_utils import OutputType, PrettyOutput, init_env, find_git_root
7
5
  from jarvis.jarvis_agent import Agent
8
6
  import re
9
7
 
8
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
9
+ from jarvis.jarvis_utils.utils import init_env
10
+
10
11
  class CodeReviewTool:
11
12
  name = "code_review"
12
13
  description = "Autonomous code review agent for code changes analysis"
@@ -35,10 +36,6 @@ class CodeReviewTool:
35
36
  "required": []
36
37
  }
37
38
 
38
- def __init__(self):
39
- init_env()
40
- self.repo_root = find_git_root()
41
-
42
39
  def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
43
40
  try:
44
41
  review_type = args.get("review_type", "current").strip()
@@ -170,13 +167,13 @@ PROPOSED DEFENSE:
170
167
  agent = Agent(
171
168
  system_prompt=system_prompt,
172
169
  name="Code Review Agent",
173
- summary_prompt="""Please generate a concise summary report of the code review, format as yaml:
170
+ summary_prompt="""Please generate a concise summary report of the code review in Chinese, format as follows:
174
171
  <REPORT>
175
- - file: xxxx.py
176
- location: [start_line_number, end_line_number]
177
- description: # Only describe issues directly observable in the diff
178
- severity: # Critical/Major/Minor based on concrete evidence
179
- suggestion: # Specific, actionable improvements for the observed code
172
+ - 文件: xxxx.py
173
+ 位置: [起始行号, 结束行号]
174
+ 描述: # 仅描述在差异中直接观察到的问题
175
+ 严重程度: # 根据具体证据分为严重/重要/次要
176
+ 建议: # 针对观察到的代码的具体改进建议
180
177
  </REPORT>""",
181
178
  is_sub_agent=True,
182
179
  output_handler=[tool_registry],
@@ -207,6 +204,8 @@ def extract_code_report(result: str) -> str:
207
204
  def main():
208
205
  """CLI entry point"""
209
206
  import argparse
207
+
208
+ init_env()
210
209
 
211
210
  parser = argparse.ArgumentParser(description='Autonomous code review tool')
212
211
  parser.add_argument('--type', choices=['commit', 'current', 'range'], default='current',
@@ -236,7 +235,7 @@ def main():
236
235
  result = tool.execute(tool_args)
237
236
 
238
237
  if result["success"]:
239
- PrettyOutput.section("Autonomous Review Result:", OutputType.SUCCESS)
238
+ PrettyOutput.section("自动代码审查结果:", OutputType.SUCCESS)
240
239
  report = extract_code_report(result["stdout"])
241
240
  PrettyOutput.print(report, OutputType.SUCCESS, lang="yaml")
242
241
 
@@ -1,9 +1,9 @@
1
- import os
2
1
  from typing import Dict, Any
3
2
  from jarvis.jarvis_code_agent.code_agent import CodeAgent
4
3
  from jarvis.jarvis_tools.git_commiter import GitCommitTool
5
4
  from jarvis.jarvis_tools.code_review import CodeReviewTool, extract_code_report
6
- from jarvis.jarvis_utils import OutputType, PrettyOutput, has_uncommitted_changes
5
+ from jarvis.jarvis_utils.git_utils import get_latest_commit_hash, has_uncommitted_changes
6
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
7
7
 
8
8
  class CreateCodeAgentTool:
9
9
  """Tool for managing the code development workflow."""
@@ -14,9 +14,6 @@ class CreateCodeAgentTool:
14
14
  "requirement": "Technical specifications for code implementation"
15
15
  }
16
16
 
17
- def _get_current_commit(self) -> str:
18
- """Get current commit hash."""
19
- return os.popen("git rev-parse HEAD").read().strip()
20
17
 
21
18
  def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
22
19
  try:
@@ -42,7 +39,7 @@ class CreateCodeAgentTool:
42
39
  }
43
40
 
44
41
  # Get current commit hash
45
- start_commit = self._get_current_commit()
42
+ start_commit = get_latest_commit_hash()
46
43
 
47
44
  # Step 2: Development
48
45
  PrettyOutput.print("开始开发...", OutputType.INFO)
@@ -50,7 +47,7 @@ class CreateCodeAgentTool:
50
47
  agent.run(requirement)
51
48
 
52
49
  # Get new commit hash after development
53
- end_commit = self._get_current_commit()
50
+ end_commit = get_latest_commit_hash()
54
51
 
55
52
  # Step 3: Code Review
56
53
  PrettyOutput.print("开始代码审查...", OutputType.INFO)
@@ -2,8 +2,8 @@ from typing import Dict, Any
2
2
 
3
3
 
4
4
  from jarvis.jarvis_agent import Agent, origin_agent_system_prompt
5
- from jarvis.jarvis_tools.registry import ToolRegistry
6
- from jarvis.jarvis_utils import OutputType, PrettyOutput
5
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
6
+
7
7
 
8
8
 
9
9
  class SubAgentTool:
@@ -3,7 +3,9 @@ import os
3
3
  import tempfile
4
4
  from pathlib import Path
5
5
 
6
- from jarvis.jarvis_utils import OutputType, PrettyOutput
6
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
7
+
8
+
7
9
 
8
10
 
9
11
  class ShellTool:
@@ -0,0 +1,58 @@
1
+ from typing import Dict, Any
2
+ import os
3
+ import tempfile
4
+ from pathlib import Path
5
+
6
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
7
+
8
+
9
+ class ShellScriptTool:
10
+ name = "execute_shell_script"
11
+ description = """Execute shell script file and return result"""
12
+ parameters = {
13
+ "type": "object",
14
+ "properties": {
15
+ "script_content": {
16
+ "type": "string",
17
+ "description": "Content of the shell script to execute"
18
+ }
19
+ },
20
+ "required": ["script_content"]
21
+ }
22
+ def execute(self, args: Dict) -> Dict[str, Any]:
23
+ """Execute shell script content"""
24
+ try:
25
+ script_content = args.get("script_content", "").strip()
26
+ if not script_content:
27
+ return {
28
+ "success": False,
29
+ "stdout": "",
30
+ "stderr": "Missing or empty script_content parameter"
31
+ }
32
+
33
+ # Create temporary script file
34
+ script_path = os.path.join(tempfile.gettempdir(), f"jarvis_script_{os.getpid()}.sh")
35
+ try:
36
+ with open(script_path, 'w', encoding='utf-8') as f:
37
+ f.write(script_content)
38
+ # Use execute_shell to run the script
39
+ from jarvis.jarvis_tools.execute_shell import ShellTool
40
+ shell_tool = ShellTool()
41
+ result = shell_tool.execute({"command": f"bash {script_path}"})
42
+
43
+ return {
44
+ "success": result["success"],
45
+ "stdout": result["stdout"],
46
+ "stderr": result["stderr"]
47
+ }
48
+ finally:
49
+ # Clean up temporary script file
50
+ Path(script_path).unlink(missing_ok=True)
51
+
52
+ except Exception as e:
53
+ PrettyOutput.print(str(e), OutputType.ERROR)
54
+ return {
55
+ "success": False,
56
+ "stdout": "",
57
+ "stderr": str(e)
58
+ }
@@ -1,7 +1,8 @@
1
- from typing import Dict, Any, List, Union
1
+ from typing import Dict, Any
2
2
  import os
3
3
 
4
- from jarvis.jarvis_utils import OutputType, PrettyOutput
4
+ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
5
+
5
6
 
6
7
 
7
8
  class FileOperationTool: