jarvis-ai-assistant 0.1.128__tar.gz → 0.1.129__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.
- {jarvis_ai_assistant-0.1.128/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.129}/PKG-INFO +1 -1
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/pyproject.toml +3 -1
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/setup.py +3 -1
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/__init__.py +1 -1
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_agent/__init__.py +8 -13
- jarvis_ai_assistant-0.1.129/src/jarvis/jarvis_agent/main.py +77 -0
- jarvis_ai_assistant-0.1.129/src/jarvis/jarvis_code_agent/builtin_input_handler.py +43 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_code_agent/code_agent.py +3 -78
- jarvis_ai_assistant-0.1.129/src/jarvis/jarvis_code_agent/file_input_handler.py +88 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_code_agent/patch.py +36 -35
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_code_agent/shell_input_handler.py +8 -2
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_multi_agent/__init__.py +51 -40
- jarvis_ai_assistant-0.1.129/src/jarvis/jarvis_tools/read_code.py +143 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/registry.py +35 -39
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/tool_generator.py +45 -17
- jarvis_ai_assistant-0.1.129/src/jarvis/jarvis_utils/__init__.py +24 -0
- jarvis_ai_assistant-0.1.129/src/jarvis/jarvis_utils/config.py +174 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_utils/embedding.py +49 -48
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_utils/git_utils.py +34 -34
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_utils/globals.py +26 -26
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_utils/input.py +61 -45
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_utils/methodology.py +22 -22
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_utils/output.py +62 -62
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_utils/utils.py +2 -2
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129/src/jarvis_ai_assistant.egg-info}/PKG-INFO +1 -1
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +4 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis_ai_assistant.egg-info/entry_points.txt +2 -0
- jarvis_ai_assistant-0.1.128/src/jarvis/jarvis_utils/__init__.py +0 -24
- jarvis_ai_assistant-0.1.128/src/jarvis/jarvis_utils/config.py +0 -138
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/MANIFEST.in +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/README.md +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/setup.cfg +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_agent/output_handler.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_code_agent/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_code_agent/file_select.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_codebase/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_codebase/main.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_dev/main.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_git_squash/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_git_squash/main.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_lsp/base.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_lsp/cpp.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_lsp/go.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_lsp/python.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_lsp/registry.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_lsp/rust.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_platform/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_platform/ai8.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_platform/base.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_platform/kimi.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_platform/ollama.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_platform/openai.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_platform/oyi.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_platform/registry.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_platform_manager/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_platform_manager/main.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_platform_manager/openai_test.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_rag/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_rag/main.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_smart_shell/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_smart_shell/main.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/__init__.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/ask_codebase.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/ask_user.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/base.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/chdir.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/code_review.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/create_code_agent.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/create_sub_agent.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/execute_shell.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/execute_shell_script.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/file_operation.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/git_commiter.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/lsp_find_definition.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/lsp_find_references.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/lsp_get_diagnostics.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/lsp_get_document_symbols.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/lsp_prepare_rename.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/methodology.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/rag.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/read_webpage.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/search_web.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_tools/select_code_files.py +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -0
- {jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "jarvis-ai-assistant"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.129"
|
|
8
8
|
description = "Jarvis: An AI assistant that uses tools to interact with the system"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "skyfire", email = "skyfireitdiy@hotmail.com" }]
|
|
@@ -69,3 +69,5 @@ jarvis-code-review = "jarvis.jarvis_tools.code_review:main"
|
|
|
69
69
|
jgc = "jarvis.jarvis_tools.git_commiter:main"
|
|
70
70
|
jarvis-dev = "jarvis.jarvis_dev.main:main"
|
|
71
71
|
jarvis-git-squash = "jarvis.jarvis_git_squash.main:main"
|
|
72
|
+
jarvis-multi-agent = "jarvis.jarvis_multi_agent:main"
|
|
73
|
+
jarvis-agent = "jarvis.jarvis_agent.main:main"
|
|
@@ -12,7 +12,7 @@ class CustomInstallCommand(install):
|
|
|
12
12
|
|
|
13
13
|
setup(
|
|
14
14
|
name="jarvis-ai-assistant",
|
|
15
|
-
version="0.1.
|
|
15
|
+
version="0.1.129",
|
|
16
16
|
author="skyfire",
|
|
17
17
|
author_email="skyfireitdiy@hotmail.com",
|
|
18
18
|
description="An AI assistant that uses various tools to interact with the system",
|
|
@@ -63,6 +63,8 @@ setup(
|
|
|
63
63
|
"jgc=jarvis.jarvis_tools.git_commiter:main",
|
|
64
64
|
"jarvis-dev=jarvis.jarvis_dev.main:main",
|
|
65
65
|
"jarvis-git-squash=jarvis.jarvis_git_squash.main:main",
|
|
66
|
+
"jarvis-multi-agent=jarvis.jarvis_multi_agent:main",
|
|
67
|
+
"jarvis-agent=jarvis.jarvis_agent.main:main",
|
|
66
68
|
],
|
|
67
69
|
},
|
|
68
70
|
python_requires=">=3.8",
|
{jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_agent/__init__.py
RENAMED
|
@@ -49,7 +49,8 @@ class Agent:
|
|
|
49
49
|
record_methodology: Optional[bool] = None,
|
|
50
50
|
need_summary: Optional[bool] = None,
|
|
51
51
|
max_context_length: Optional[int] = None,
|
|
52
|
-
execute_tool_confirm: Optional[bool] = None
|
|
52
|
+
execute_tool_confirm: Optional[bool] = None,
|
|
53
|
+
multiline_inputer: Optional[Callable[[str], str]] = None):
|
|
53
54
|
self.name = make_agent_name(name)
|
|
54
55
|
self.description = description
|
|
55
56
|
# 初始化平台和模型
|
|
@@ -69,7 +70,8 @@ class Agent:
|
|
|
69
70
|
|
|
70
71
|
self.model.set_suppress_output(False)
|
|
71
72
|
|
|
72
|
-
self.output_handler = output_handler
|
|
73
|
+
self.output_handler = output_handler if output_handler else [ToolRegistry()]
|
|
74
|
+
self.multiline_inputer = multiline_inputer if multiline_inputer else get_multiline_input
|
|
73
75
|
|
|
74
76
|
self.record_methodology = record_methodology if record_methodology is not None else is_record_methodology()
|
|
75
77
|
self.use_methodology = use_methodology if use_methodology is not None else is_use_methodology()
|
|
@@ -287,23 +289,17 @@ class Agent:
|
|
|
287
289
|
return "任务完成"
|
|
288
290
|
|
|
289
291
|
|
|
290
|
-
def run(self, user_input: str
|
|
292
|
+
def run(self, user_input: str) -> Any:
|
|
291
293
|
"""Process user input and execute the task.
|
|
292
294
|
|
|
293
295
|
Args:
|
|
294
296
|
user_input: My task description or request
|
|
295
|
-
file_list: Optional list of files to process
|
|
296
297
|
|
|
297
298
|
Returns:
|
|
298
299
|
str|Dict: Task summary report or message to send
|
|
299
300
|
"""
|
|
300
301
|
try:
|
|
301
302
|
set_agent(self.name, self)
|
|
302
|
-
with yaspin(text="准备环境...", color="cyan") as spinner:
|
|
303
|
-
if file_list:
|
|
304
|
-
self.model.upload_files(file_list) # type: ignore
|
|
305
|
-
spinner.text = "环境准备完成"
|
|
306
|
-
spinner.ok("✅")
|
|
307
303
|
|
|
308
304
|
self.prompt = f"{user_input}"
|
|
309
305
|
|
|
@@ -338,7 +334,7 @@ class Agent:
|
|
|
338
334
|
return self._complete_task()
|
|
339
335
|
|
|
340
336
|
# 获取用户输入
|
|
341
|
-
user_input =
|
|
337
|
+
user_input = self.multiline_inputer(f"{self.name}: 请输入,或输入空行来结束当前任务:")
|
|
342
338
|
|
|
343
339
|
if user_input:
|
|
344
340
|
self.prompt = user_input
|
|
@@ -551,7 +547,6 @@ def main():
|
|
|
551
547
|
# Add argument parser
|
|
552
548
|
init_env()
|
|
553
549
|
parser = argparse.ArgumentParser(description='Jarvis AI assistant')
|
|
554
|
-
parser.add_argument('-f', '--files', nargs='*', help='List of files to process')
|
|
555
550
|
parser.add_argument('-p', '--platform', type=str, help='Platform to use')
|
|
556
551
|
parser.add_argument('-m', '--model', type=str, help='Model to use')
|
|
557
552
|
args = parser.parse_args()
|
|
@@ -566,7 +561,7 @@ def main():
|
|
|
566
561
|
selected_task = _select_task(tasks)
|
|
567
562
|
if selected_task:
|
|
568
563
|
PrettyOutput.print(f"执行任务: {selected_task}", OutputType.INFO)
|
|
569
|
-
agent.run(selected_task
|
|
564
|
+
agent.run(selected_task)
|
|
570
565
|
return 0
|
|
571
566
|
|
|
572
567
|
# 如果没有选择预定义任务,进入交互模式
|
|
@@ -575,7 +570,7 @@ def main():
|
|
|
575
570
|
user_input = get_multiline_input("请输入你的任务(输入空行退出):")
|
|
576
571
|
if not user_input:
|
|
577
572
|
break
|
|
578
|
-
agent.run(user_input
|
|
573
|
+
agent.run(user_input)
|
|
579
574
|
except Exception as e:
|
|
580
575
|
PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
|
|
581
576
|
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import yaml
|
|
3
|
+
import os
|
|
4
|
+
from typing import Optional, List
|
|
5
|
+
from jarvis.jarvis_agent import Agent
|
|
6
|
+
from jarvis.jarvis_utils.input import get_multiline_input
|
|
7
|
+
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
8
|
+
from jarvis.jarvis_utils.utils import init_env
|
|
9
|
+
|
|
10
|
+
# 从__init__.py导入系统提示
|
|
11
|
+
from jarvis.jarvis_agent import origin_agent_system_prompt
|
|
12
|
+
|
|
13
|
+
def load_config(config_path: str) -> dict:
|
|
14
|
+
"""Load configuration from YAML file
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
config_path: Path to the YAML configuration file
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
dict: Configuration dictionary
|
|
21
|
+
"""
|
|
22
|
+
if not os.path.exists(config_path):
|
|
23
|
+
PrettyOutput.print(f"配置文件 {config_path} 不存在,使用默认配置", OutputType.WARNING)
|
|
24
|
+
return {}
|
|
25
|
+
|
|
26
|
+
with open(config_path, 'r', encoding='utf-8') as f:
|
|
27
|
+
try:
|
|
28
|
+
config = yaml.safe_load(f)
|
|
29
|
+
return config if config else {}
|
|
30
|
+
except yaml.YAMLError as e:
|
|
31
|
+
PrettyOutput.print(f"配置文件解析失败: {str(e)}", OutputType.ERROR)
|
|
32
|
+
return {}
|
|
33
|
+
|
|
34
|
+
def main():
|
|
35
|
+
"""Main entry point for Jarvis agent"""
|
|
36
|
+
# Initialize environment
|
|
37
|
+
init_env()
|
|
38
|
+
|
|
39
|
+
# Set up argument parser
|
|
40
|
+
parser = argparse.ArgumentParser(description='Jarvis AI assistant')
|
|
41
|
+
parser.add_argument('-c', '--config', type=str, required=True,
|
|
42
|
+
help='Path to the YAML configuration file')
|
|
43
|
+
parser.add_argument('-t', '--task', type=str,
|
|
44
|
+
help='Initial task to execute')
|
|
45
|
+
args = parser.parse_args()
|
|
46
|
+
|
|
47
|
+
# Load configuration
|
|
48
|
+
config = load_config(args.config)
|
|
49
|
+
|
|
50
|
+
# Create and run agent
|
|
51
|
+
try:
|
|
52
|
+
agent = Agent(**config)
|
|
53
|
+
|
|
54
|
+
# Run agent with initial task if specified
|
|
55
|
+
if args.task:
|
|
56
|
+
PrettyOutput.print(f"执行初始任务: {args.task}", OutputType.INFO)
|
|
57
|
+
agent.run(args.task)
|
|
58
|
+
return 0
|
|
59
|
+
|
|
60
|
+
# Enter interactive mode if no initial task
|
|
61
|
+
while True:
|
|
62
|
+
try:
|
|
63
|
+
user_input = get_multiline_input("请输入你的任务(输入空行退出):")
|
|
64
|
+
if not user_input:
|
|
65
|
+
break
|
|
66
|
+
agent.run(user_input)
|
|
67
|
+
except Exception as e:
|
|
68
|
+
PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
|
|
69
|
+
|
|
70
|
+
except Exception as e:
|
|
71
|
+
PrettyOutput.print(f"初始化错误: {str(e)}", OutputType.ERROR)
|
|
72
|
+
return 1
|
|
73
|
+
|
|
74
|
+
return 0
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
exit(main())
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Any, Tuple
|
|
3
|
+
|
|
4
|
+
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def builtin_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
|
|
8
|
+
"""
|
|
9
|
+
处理内置的特殊输入标记,并追加相应的提示词
|
|
10
|
+
|
|
11
|
+
参数:
|
|
12
|
+
user_input: 用户输入
|
|
13
|
+
agent: 代理对象
|
|
14
|
+
|
|
15
|
+
返回:
|
|
16
|
+
Tuple[str, bool]: 处理后的输入和是否需要进一步处理
|
|
17
|
+
"""
|
|
18
|
+
# 查找特殊标记
|
|
19
|
+
special_tags = re.findall(r"'<([^>]+)>'", user_input)
|
|
20
|
+
|
|
21
|
+
if not special_tags:
|
|
22
|
+
return user_input, False
|
|
23
|
+
|
|
24
|
+
# 使用集合去重
|
|
25
|
+
processed_tags = set()
|
|
26
|
+
# 处理每个标记
|
|
27
|
+
for tag in special_tags:
|
|
28
|
+
if tag in processed_tags:
|
|
29
|
+
continue
|
|
30
|
+
processed_tags.add(tag)
|
|
31
|
+
|
|
32
|
+
if tag == "CodeBase":
|
|
33
|
+
user_input = user_input.replace(f"'<{tag}>'", "")
|
|
34
|
+
user_input += "\n请使用ask_codebase工具查询代码库"
|
|
35
|
+
elif tag == "Web":
|
|
36
|
+
user_input = user_input.replace(f"'<{tag}>'", "")
|
|
37
|
+
user_input += "\n请使用search_web工具进行网页搜索"
|
|
38
|
+
elif tag == "RAG":
|
|
39
|
+
user_input = user_input.replace(f"'<{tag}>'", "")
|
|
40
|
+
user_input += "\n请使用rag工具进行知识库检索"
|
|
41
|
+
# 移除对未知标记的警告输出
|
|
42
|
+
|
|
43
|
+
return user_input, False
|
|
@@ -6,6 +6,8 @@ from typing import Any, Tuple
|
|
|
6
6
|
from yaspin import yaspin
|
|
7
7
|
|
|
8
8
|
from jarvis.jarvis_agent import Agent
|
|
9
|
+
from jarvis.jarvis_code_agent.builtin_input_handler import builtin_input_handler
|
|
10
|
+
from jarvis.jarvis_code_agent.file_input_handler import file_input_handler
|
|
9
11
|
from jarvis.jarvis_code_agent.shell_input_handler import shell_input_handler
|
|
10
12
|
from jarvis.jarvis_code_agent.patch import PatchOutputHandler
|
|
11
13
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
@@ -21,83 +23,6 @@ from jarvis.jarvis_utils.utils import init_env, user_confirm
|
|
|
21
23
|
|
|
22
24
|
|
|
23
25
|
|
|
24
|
-
def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
|
|
25
|
-
prompt = user_input
|
|
26
|
-
files = []
|
|
27
|
-
|
|
28
|
-
file_refs = re.findall(r"'([^']+)'", user_input)
|
|
29
|
-
for ref in file_refs:
|
|
30
|
-
# Handle file:start,end or file:start:end format
|
|
31
|
-
if ':' in ref:
|
|
32
|
-
file_path, line_range = ref.split(':', 1)
|
|
33
|
-
# Initialize with default values
|
|
34
|
-
start_line = 1 # 1-based
|
|
35
|
-
end_line = -1
|
|
36
|
-
|
|
37
|
-
# Process line range if specified
|
|
38
|
-
if ',' in line_range or ':' in line_range:
|
|
39
|
-
try:
|
|
40
|
-
raw_start, raw_end = map(int, re.split(r'[,:]', line_range))
|
|
41
|
-
|
|
42
|
-
# Handle special values and Python-style negative indices
|
|
43
|
-
try:
|
|
44
|
-
with open(file_path, 'r', encoding='utf-8') as f:
|
|
45
|
-
total_lines = len(f.readlines())
|
|
46
|
-
except FileNotFoundError:
|
|
47
|
-
PrettyOutput.print(f"文件不存在: {file_path}", OutputType.WARNING)
|
|
48
|
-
continue
|
|
49
|
-
# Process start line
|
|
50
|
-
if raw_start == 0: # 0表示整个文件
|
|
51
|
-
start_line = 1
|
|
52
|
-
end_line = total_lines
|
|
53
|
-
else:
|
|
54
|
-
start_line = raw_start if raw_start > 0 else total_lines + raw_start + 1
|
|
55
|
-
|
|
56
|
-
# Process end line
|
|
57
|
-
if raw_end == 0: # 0表示整个文件(如果start也是0)
|
|
58
|
-
end_line = total_lines
|
|
59
|
-
else:
|
|
60
|
-
end_line = raw_end if raw_end > 0 else total_lines + raw_end + 1
|
|
61
|
-
|
|
62
|
-
# Auto-correct ranges
|
|
63
|
-
start_line = max(1, min(start_line, total_lines))
|
|
64
|
-
end_line = max(start_line, min(end_line, total_lines))
|
|
65
|
-
|
|
66
|
-
# Final validation
|
|
67
|
-
if start_line < 1 or end_line > total_lines or start_line > end_line:
|
|
68
|
-
raise ValueError
|
|
69
|
-
|
|
70
|
-
except:
|
|
71
|
-
continue
|
|
72
|
-
|
|
73
|
-
# Add file if it exists
|
|
74
|
-
if os.path.isfile(file_path):
|
|
75
|
-
files.append({
|
|
76
|
-
"path": file_path,
|
|
77
|
-
"start_line": start_line,
|
|
78
|
-
"end_line": end_line
|
|
79
|
-
})
|
|
80
|
-
else:
|
|
81
|
-
# Handle simple file path
|
|
82
|
-
if os.path.isfile(ref):
|
|
83
|
-
files.append({
|
|
84
|
-
"path": ref,
|
|
85
|
-
"start_line": 1, # 1-based
|
|
86
|
-
"end_line": -1
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
# Read and process files if any were found
|
|
90
|
-
if files:
|
|
91
|
-
with yaspin(text="正在读取文件...", color="cyan") as spinner:
|
|
92
|
-
result = FileOperationTool().execute({"operation":"read","files": files})
|
|
93
|
-
if result["success"]:
|
|
94
|
-
spinner.text = "文件读取完成"
|
|
95
|
-
spinner.ok("✅")
|
|
96
|
-
return result["stdout"] + "\n" + prompt, False
|
|
97
|
-
|
|
98
|
-
return prompt, False
|
|
99
|
-
|
|
100
|
-
|
|
101
26
|
|
|
102
27
|
class CodeAgent:
|
|
103
28
|
def __init__(self):
|
|
@@ -208,7 +133,7 @@ class CodeAgent:
|
|
|
208
133
|
output_handler=[tool_registry, PatchOutputHandler()],
|
|
209
134
|
platform=PlatformRegistry().get_codegen_platform(),
|
|
210
135
|
record_methodology=False,
|
|
211
|
-
input_handler=[shell_input_handler, file_input_handler],
|
|
136
|
+
input_handler=[shell_input_handler, file_input_handler, builtin_input_handler],
|
|
212
137
|
need_summary=False)
|
|
213
138
|
|
|
214
139
|
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
import re
|
|
5
|
+
from typing import Any, Tuple
|
|
6
|
+
|
|
7
|
+
from yaspin import yaspin
|
|
8
|
+
|
|
9
|
+
from jarvis.jarvis_tools.file_operation import FileOperationTool
|
|
10
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
|
|
14
|
+
prompt = user_input
|
|
15
|
+
files = []
|
|
16
|
+
|
|
17
|
+
file_refs = re.findall(r"'([^']+)'", user_input)
|
|
18
|
+
for ref in file_refs:
|
|
19
|
+
# Handle file:start,end or file:start:end format
|
|
20
|
+
if ':' in ref:
|
|
21
|
+
file_path, line_range = ref.split(':', 1)
|
|
22
|
+
# Initialize with default values
|
|
23
|
+
start_line = 1 # 1-based
|
|
24
|
+
end_line = -1
|
|
25
|
+
|
|
26
|
+
# Process line range if specified
|
|
27
|
+
if ',' in line_range or ':' in line_range:
|
|
28
|
+
try:
|
|
29
|
+
raw_start, raw_end = map(int, re.split(r'[,:]', line_range))
|
|
30
|
+
|
|
31
|
+
# Handle special values and Python-style negative indices
|
|
32
|
+
try:
|
|
33
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
34
|
+
total_lines = len(f.readlines())
|
|
35
|
+
except FileNotFoundError:
|
|
36
|
+
PrettyOutput.print(f"文件不存在: {file_path}", OutputType.WARNING)
|
|
37
|
+
continue
|
|
38
|
+
# Process start line
|
|
39
|
+
if raw_start == 0: # 0表示整个文件
|
|
40
|
+
start_line = 1
|
|
41
|
+
end_line = total_lines
|
|
42
|
+
else:
|
|
43
|
+
start_line = raw_start if raw_start > 0 else total_lines + raw_start + 1
|
|
44
|
+
|
|
45
|
+
# Process end line
|
|
46
|
+
if raw_end == 0: # 0表示整个文件(如果start也是0)
|
|
47
|
+
end_line = total_lines
|
|
48
|
+
else:
|
|
49
|
+
end_line = raw_end if raw_end > 0 else total_lines + raw_end + 1
|
|
50
|
+
|
|
51
|
+
# Auto-correct ranges
|
|
52
|
+
start_line = max(1, min(start_line, total_lines))
|
|
53
|
+
end_line = max(start_line, min(end_line, total_lines))
|
|
54
|
+
|
|
55
|
+
# Final validation
|
|
56
|
+
if start_line < 1 or end_line > total_lines or start_line > end_line:
|
|
57
|
+
raise ValueError
|
|
58
|
+
|
|
59
|
+
except:
|
|
60
|
+
continue
|
|
61
|
+
|
|
62
|
+
# Add file if it exists
|
|
63
|
+
if os.path.isfile(file_path):
|
|
64
|
+
files.append({
|
|
65
|
+
"path": file_path,
|
|
66
|
+
"start_line": start_line,
|
|
67
|
+
"end_line": end_line
|
|
68
|
+
})
|
|
69
|
+
else:
|
|
70
|
+
# Handle simple file path
|
|
71
|
+
if os.path.isfile(ref):
|
|
72
|
+
files.append({
|
|
73
|
+
"path": ref,
|
|
74
|
+
"start_line": 1, # 1-based
|
|
75
|
+
"end_line": -1
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
# Read and process files if any were found
|
|
79
|
+
if files:
|
|
80
|
+
with yaspin(text="正在读取文件...", color="cyan") as spinner:
|
|
81
|
+
result = FileOperationTool().execute({"operation":"read","files": files})
|
|
82
|
+
if result["success"]:
|
|
83
|
+
spinner.text = "文件读取完成"
|
|
84
|
+
spinner.ok("✅")
|
|
85
|
+
return result["stdout"] + "\n" + prompt, False
|
|
86
|
+
|
|
87
|
+
return prompt, False
|
|
88
|
+
|
{jarvis_ai_assistant-0.1.128 → jarvis_ai_assistant-0.1.129}/src/jarvis/jarvis_code_agent/patch.py
RENAMED
|
@@ -9,6 +9,7 @@ from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
|
9
9
|
from jarvis.jarvis_tools.git_commiter import GitCommitTool
|
|
10
10
|
from jarvis.jarvis_tools.execute_shell_script import ShellScriptTool
|
|
11
11
|
from jarvis.jarvis_tools.file_operation import FileOperationTool
|
|
12
|
+
from jarvis.jarvis_tools.read_code import ReadCodeTool
|
|
12
13
|
from jarvis.jarvis_utils.config import is_confirm_before_apply_patch
|
|
13
14
|
from jarvis.jarvis_utils.git_utils import get_commits_between, get_latest_commit_hash
|
|
14
15
|
from jarvis.jarvis_utils.input import get_multiline_input
|
|
@@ -39,7 +40,7 @@ Reason: [修改原因]
|
|
|
39
40
|
--------------------------------
|
|
40
41
|
规则:
|
|
41
42
|
1. 代码片段必须包含足够的上下文(前后各3行)
|
|
42
|
-
2.
|
|
43
|
+
2. 我可以看到完整代码,所以只需显示修改的代码部分,不需要将整个文件内容都显示出来
|
|
43
44
|
3. 保留原始缩进和格式
|
|
44
45
|
4. 对于新文件,提供完整代码
|
|
45
46
|
5. 修改现有文件时,保留周围未更改的代码
|
|
@@ -184,7 +185,7 @@ def handle_commit_workflow()->bool:
|
|
|
184
185
|
commit_result = git_commiter.execute({})
|
|
185
186
|
return commit_result["success"]
|
|
186
187
|
|
|
187
|
-
|
|
188
|
+
|
|
188
189
|
def handle_code_operation(filepath: str, patch_content: str) -> bool:
|
|
189
190
|
"""处理基于上下文的代码片段"""
|
|
190
191
|
with yaspin(text=f"正在修改文件 {filepath}...", color="cyan") as spinner:
|
|
@@ -195,10 +196,11 @@ def handle_code_operation(filepath: str, patch_content: str) -> bool:
|
|
|
195
196
|
os.makedirs(os.path.dirname(filepath), exist_ok=True)
|
|
196
197
|
open(filepath, 'w', encoding='utf-8').close()
|
|
197
198
|
spinner.write("✅ 文件创建完成")
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
199
|
+
with spinner.hidden():
|
|
200
|
+
old_file_content = FileOperationTool().execute({"operation": "read", "files": [{"path": filepath}]})
|
|
201
|
+
if not old_file_content["success"]:
|
|
202
|
+
spinner.write("❌ 文件读取失败")
|
|
203
|
+
return False
|
|
202
204
|
|
|
203
205
|
prompt = f"""
|
|
204
206
|
你是一个代码审查员,请审查以下代码并将其与上下文合并。
|
|
@@ -222,45 +224,44 @@ def handle_code_operation(filepath: str, patch_content: str) -> bool:
|
|
|
222
224
|
[merged_code]
|
|
223
225
|
</MERGED_CODE>
|
|
224
226
|
"""
|
|
225
|
-
PrettyOutput.section("代码生成", OutputType.SYSTEM)
|
|
226
227
|
model = PlatformRegistry().get_codegen_platform()
|
|
227
|
-
model.set_suppress_output(
|
|
228
|
+
model.set_suppress_output(True)
|
|
228
229
|
count = 30
|
|
229
230
|
start_line = -1
|
|
230
231
|
end_line = -1
|
|
231
232
|
code = []
|
|
232
233
|
finished = False
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
start_line = response.index("<MERGED_CODE>") + 1
|
|
239
|
-
except:
|
|
240
|
-
return False
|
|
234
|
+
while count>0:
|
|
235
|
+
count -= 1
|
|
236
|
+
response = model.chat_until_success(prompt).splitlines()
|
|
237
|
+
try:
|
|
238
|
+
start_line = response.index("<MERGED_CODE>") + 1
|
|
241
239
|
try:
|
|
242
240
|
end_line = response.index("</MERGED_CODE>")
|
|
241
|
+
code = response[start_line:end_line]
|
|
243
242
|
except:
|
|
244
|
-
return False
|
|
245
|
-
code = response[start_line:end_line]
|
|
246
|
-
try:
|
|
247
|
-
response.index("<!!!FINISHED!!!>")
|
|
248
|
-
finished = True
|
|
249
|
-
break
|
|
250
|
-
except:
|
|
251
|
-
prompt += f"""继续输出接下来的300行代码
|
|
252
|
-
要求:
|
|
253
|
-
1. 严格保留原始代码的格式、空行和缩进
|
|
254
|
-
2. 仅在<MERGED_CODE>块中包含实际代码内容,包括空行和缩进
|
|
255
|
-
3. 绝对不要使用markdown代码块(```)或反引号,除非修改的是markdown文件
|
|
256
|
-
4. 除了合并后的代码,不要输出任何其他文本
|
|
257
|
-
5. 所有代码输出完成后,输出<!!!FINISHED!!!>
|
|
258
|
-
"""
|
|
259
243
|
pass
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
244
|
+
except:
|
|
245
|
+
pass
|
|
246
|
+
|
|
247
|
+
try:
|
|
248
|
+
response.index("<!!!FINISHED!!!>")
|
|
249
|
+
finished = True
|
|
250
|
+
break
|
|
251
|
+
except:
|
|
252
|
+
prompt += f"""继续输出接下来的300行代码
|
|
253
|
+
要求:
|
|
254
|
+
1. 严格保留原始代码的格式、空行和缩进
|
|
255
|
+
2. 仅在<MERGED_CODE>块中包含实际代码内容,包括空行和缩进
|
|
256
|
+
3. 绝对不要使用markdown代码块(```)或反引号,除非修改的是markdown文件
|
|
257
|
+
4. 除了合并后的代码,不要输出任何其他文本
|
|
258
|
+
5. 所有代码输出完成后,输出<!!!FINISHED!!!>
|
|
259
|
+
"""
|
|
260
|
+
pass
|
|
261
|
+
if not finished:
|
|
262
|
+
spinner.text = "生成代码失败"
|
|
263
|
+
spinner.fail("❌")
|
|
264
|
+
return False
|
|
264
265
|
# 写入合并后的代码
|
|
265
266
|
spinner.text = "写入合并后的代码..."
|
|
266
267
|
with open(filepath, 'w', encoding='utf-8') as f:
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from typing import Any, Tuple
|
|
4
4
|
|
|
5
5
|
from jarvis.jarvis_tools.execute_shell_script import ShellScriptTool
|
|
6
|
+
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
6
7
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
7
8
|
from jarvis.jarvis_utils.utils import user_confirm
|
|
8
9
|
|
|
@@ -16,7 +17,12 @@ def shell_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
|
|
|
16
17
|
script = '\n'.join([c[1:] for c in cmdline])
|
|
17
18
|
PrettyOutput.print(script, OutputType.CODE, lang="bash")
|
|
18
19
|
if user_confirm(f"是否要执行以上shell脚本?", default=True):
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
output = ToolRegistry().handle_tool_calls({
|
|
21
|
+
"name": "execute_shell_script",
|
|
22
|
+
"arguments": {
|
|
23
|
+
"script_content": script
|
|
24
|
+
}
|
|
25
|
+
})
|
|
26
|
+
return f"{user_input}\n\n用户执行以下脚本:\n{script}\n\n执行结果:\n{output}", False
|
|
21
27
|
return user_input, False
|
|
22
28
|
|