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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +19 -21
- jarvis/jarvis_code_agent/code_agent.py +205 -119
- jarvis/jarvis_code_agent/file_select.py +6 -105
- jarvis/jarvis_code_agent/patch.py +192 -259
- jarvis/jarvis_codebase/main.py +6 -2
- jarvis/jarvis_dev/main.py +6 -4
- jarvis/jarvis_git_squash/__init__.py +0 -0
- jarvis/jarvis_git_squash/main.py +81 -0
- jarvis/jarvis_lsp/cpp.py +1 -1
- jarvis/jarvis_lsp/go.py +1 -1
- jarvis/jarvis_lsp/registry.py +2 -2
- jarvis/jarvis_lsp/rust.py +1 -1
- jarvis/jarvis_multi_agent/__init__.py +1 -1
- jarvis/jarvis_platform/ai8.py +2 -1
- jarvis/jarvis_platform/base.py +20 -25
- jarvis/jarvis_platform/kimi.py +2 -3
- jarvis/jarvis_platform/ollama.py +3 -1
- jarvis/jarvis_platform/openai.py +1 -1
- jarvis/jarvis_platform/oyi.py +2 -1
- jarvis/jarvis_platform/registry.py +2 -1
- jarvis/jarvis_platform_manager/main.py +4 -6
- jarvis/jarvis_platform_manager/openai_test.py +0 -1
- jarvis/jarvis_rag/main.py +5 -2
- jarvis/jarvis_smart_shell/main.py +9 -4
- jarvis/jarvis_tools/ask_codebase.py +12 -7
- jarvis/jarvis_tools/ask_user.py +3 -2
- jarvis/jarvis_tools/base.py +21 -7
- jarvis/jarvis_tools/chdir.py +25 -1
- jarvis/jarvis_tools/code_review.py +13 -14
- jarvis/jarvis_tools/create_code_agent.py +4 -7
- jarvis/jarvis_tools/create_sub_agent.py +2 -2
- jarvis/jarvis_tools/execute_shell.py +3 -1
- jarvis/jarvis_tools/execute_shell_script.py +58 -0
- jarvis/jarvis_tools/file_operation.py +3 -2
- jarvis/jarvis_tools/git_commiter.py +26 -17
- jarvis/jarvis_tools/lsp_find_definition.py +1 -1
- jarvis/jarvis_tools/lsp_find_references.py +1 -1
- jarvis/jarvis_tools/lsp_get_diagnostics.py +19 -11
- jarvis/jarvis_tools/lsp_get_document_symbols.py +1 -1
- jarvis/jarvis_tools/lsp_prepare_rename.py +1 -1
- jarvis/jarvis_tools/lsp_validate_edit.py +1 -1
- jarvis/jarvis_tools/methodology.py +4 -1
- jarvis/jarvis_tools/rag.py +22 -15
- jarvis/jarvis_tools/read_code.py +4 -3
- jarvis/jarvis_tools/read_webpage.py +2 -1
- jarvis/jarvis_tools/registry.py +4 -1
- jarvis/jarvis_tools/{search.py → search_web.py} +5 -3
- jarvis/jarvis_tools/select_code_files.py +1 -1
- jarvis/jarvis_utils/__init__.py +19 -941
- jarvis/jarvis_utils/config.py +138 -0
- jarvis/jarvis_utils/embedding.py +201 -0
- jarvis/jarvis_utils/git_utils.py +120 -0
- jarvis/jarvis_utils/globals.py +82 -0
- jarvis/jarvis_utils/input.py +161 -0
- jarvis/jarvis_utils/methodology.py +128 -0
- jarvis/jarvis_utils/output.py +235 -0
- jarvis/jarvis_utils/utils.py +150 -0
- jarvis_ai_assistant-0.1.125.dist-info/METADATA +291 -0
- jarvis_ai_assistant-0.1.125.dist-info/RECORD +75 -0
- {jarvis_ai_assistant-0.1.123.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/WHEEL +1 -1
- {jarvis_ai_assistant-0.1.123.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/entry_points.txt +1 -0
- jarvis/jarvis_code_agent/relevant_files.py +0 -117
- jarvis_ai_assistant-0.1.123.dist-info/METADATA +0 -461
- jarvis_ai_assistant-0.1.123.dist-info/RECORD +0 -65
- {jarvis_ai_assistant-0.1.123.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.123.dist-info → jarvis_ai_assistant-0.1.125.dist-info}/top_level.txt +0 -0
jarvis/jarvis_lsp/registry.py
CHANGED
|
@@ -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
|
|
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.
|
|
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
|
|
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:
|
jarvis/jarvis_platform/ai8.py
CHANGED
|
@@ -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
|
|
jarvis/jarvis_platform/base.py
CHANGED
|
@@ -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
|
|
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
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
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'
|
|
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)
|
jarvis/jarvis_platform/kimi.py
CHANGED
|
@@ -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
|
|
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
|
|
jarvis/jarvis_platform/ollama.py
CHANGED
|
@@ -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
|
|
jarvis/jarvis_platform/openai.py
CHANGED
|
@@ -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
|
|
5
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
6
6
|
|
|
7
7
|
class OpenAIModel(BasePlatform):
|
|
8
8
|
platform_name = "openai"
|
jarvis/jarvis_platform/oyi.py
CHANGED
|
@@ -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
|
|
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()
|
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
|
-
|
|
8
|
-
from yaspin
|
|
7
|
+
|
|
8
|
+
from yaspin import yaspin
|
|
9
9
|
|
|
10
10
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
11
|
-
from jarvis.jarvis_utils import
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
jarvis/jarvis_tools/ask_user.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from typing import Dict, Any
|
|
2
|
-
|
|
3
|
-
from jarvis.jarvis_utils import get_multiline_input
|
|
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"
|
jarvis/jarvis_tools/base.py
CHANGED
|
@@ -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
|
-
"""
|
|
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
|
-
"""
|
|
28
|
+
"""
|
|
29
|
+
执行工具函数
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
arguments (Dict): 工具执行所需的参数
|
|
33
|
+
|
|
34
|
+
Returns:
|
|
35
|
+
Dict[str, Any]: 工具执行结果
|
|
36
|
+
"""
|
|
23
37
|
return self.func(arguments)
|
jarvis/jarvis_tools/chdir.py
CHANGED
|
@@ -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
|
|
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
|
|
170
|
+
summary_prompt="""Please generate a concise summary report of the code review in Chinese, format as follows:
|
|
174
171
|
<REPORT>
|
|
175
|
-
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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("
|
|
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
|
|
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 =
|
|
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 =
|
|
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.
|
|
6
|
-
|
|
5
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
6
|
+
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class SubAgentTool:
|
|
@@ -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
|
+
}
|