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.
- jarvis/__init__.py +1 -1
- jarvis/agent.py +72 -41
- jarvis/jarvis_code_agent/code_agent.py +23 -5
- jarvis/jarvis_code_agent/file_select.py +16 -16
- jarvis/jarvis_code_agent/patch.py +17 -11
- jarvis/jarvis_code_agent/relevant_files.py +33 -40
- jarvis/jarvis_codebase/main.py +57 -48
- jarvis/jarvis_lsp/cpp.py +1 -1
- jarvis/jarvis_lsp/go.py +1 -1
- jarvis/jarvis_lsp/python.py +0 -2
- jarvis/jarvis_lsp/registry.py +13 -13
- jarvis/jarvis_lsp/rust.py +1 -1
- jarvis/jarvis_platform/ai8.py +14 -14
- jarvis/jarvis_platform/base.py +1 -1
- jarvis/jarvis_platform/kimi.py +17 -17
- jarvis/jarvis_platform/ollama.py +14 -14
- jarvis/jarvis_platform/openai.py +8 -8
- jarvis/jarvis_platform/oyi.py +19 -19
- jarvis/jarvis_platform/registry.py +6 -6
- jarvis/jarvis_platform_manager/main.py +17 -17
- jarvis/jarvis_rag/main.py +25 -25
- jarvis/jarvis_smart_shell/main.py +6 -6
- jarvis/jarvis_tools/ask_codebase.py +3 -3
- jarvis/jarvis_tools/ask_user.py +2 -2
- jarvis/jarvis_tools/create_code_agent.py +8 -8
- jarvis/jarvis_tools/create_sub_agent.py +2 -2
- jarvis/jarvis_tools/execute_shell.py +2 -2
- jarvis/jarvis_tools/file_operation.py +1 -1
- jarvis/jarvis_tools/git_commiter.py +8 -5
- jarvis/jarvis_tools/methodology.py +3 -3
- jarvis/jarvis_tools/rag.py +3 -3
- jarvis/jarvis_tools/read_code.py +1 -1
- jarvis/jarvis_tools/read_webpage.py +19 -6
- jarvis/jarvis_tools/registry.py +11 -11
- jarvis/jarvis_tools/search.py +88 -27
- jarvis/jarvis_tools/select_code_files.py +1 -1
- jarvis/jarvis_tools/tool_generator.py +182 -0
- jarvis/utils.py +69 -28
- jarvis_ai_assistant-0.1.113.dist-info/METADATA +460 -0
- jarvis_ai_assistant-0.1.113.dist-info/RECORD +64 -0
- jarvis_ai_assistant-0.1.111.dist-info/METADATA +0 -461
- jarvis_ai_assistant-0.1.111.dist-info/RECORD +0 -63
- {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.111.dist-info → jarvis_ai_assistant-0.1.113.dist-info}/top_level.txt +0 -0
jarvis/jarvis_rag/main.py
CHANGED
|
@@ -154,9 +154,9 @@ class RAGTool:
|
|
|
154
154
|
try:
|
|
155
155
|
self.embedding_model = load_embedding_model()
|
|
156
156
|
self.vector_dim = self.embedding_model.get_sentence_embedding_dimension()
|
|
157
|
-
PrettyOutput.print("
|
|
157
|
+
PrettyOutput.print("模型加载完成", output_type=OutputType.SUCCESS)
|
|
158
158
|
except Exception as e:
|
|
159
|
-
PrettyOutput.print(f"
|
|
159
|
+
PrettyOutput.print(f"加载模型失败: {str(e)}", output_type=OutputType.ERROR)
|
|
160
160
|
raise
|
|
161
161
|
|
|
162
162
|
# 修改缓存相关初始化
|
|
@@ -218,7 +218,7 @@ class RAGTool:
|
|
|
218
218
|
file_cache = pickle.load(f)
|
|
219
219
|
self.documents.extend(file_cache["documents"])
|
|
220
220
|
except Exception as e:
|
|
221
|
-
PrettyOutput.print(f"
|
|
221
|
+
PrettyOutput.print(f"加载缓存失败,文件路径:{file_path}: {str(e)}",
|
|
222
222
|
output_type=OutputType.WARNING)
|
|
223
223
|
|
|
224
224
|
# 重建向量索引
|
|
@@ -238,11 +238,11 @@ class RAGTool:
|
|
|
238
238
|
vectors = np.vstack(vectors)
|
|
239
239
|
self._build_index(vectors)
|
|
240
240
|
|
|
241
|
-
PrettyOutput.print(f"
|
|
241
|
+
PrettyOutput.print(f"加载 {len(self.documents)} 个文档片段",
|
|
242
242
|
output_type=OutputType.INFO)
|
|
243
243
|
|
|
244
244
|
except Exception as e:
|
|
245
|
-
PrettyOutput.print(f"
|
|
245
|
+
PrettyOutput.print(f"加载缓存索引失败: {str(e)}",
|
|
246
246
|
output_type=OutputType.WARNING)
|
|
247
247
|
self.documents = []
|
|
248
248
|
self.index = None
|
|
@@ -276,7 +276,7 @@ class RAGTool:
|
|
|
276
276
|
pickle.dump(index_data, f)
|
|
277
277
|
|
|
278
278
|
except Exception as e:
|
|
279
|
-
PrettyOutput.print(f"
|
|
279
|
+
PrettyOutput.print(f"保存缓存失败: {str(e)}", output_type=OutputType.ERROR)
|
|
280
280
|
|
|
281
281
|
def _build_index(self, vectors: np.ndarray):
|
|
282
282
|
"""Build FAISS index"""
|
|
@@ -382,7 +382,7 @@ class RAGTool:
|
|
|
382
382
|
|
|
383
383
|
return get_embedding_batch(self.embedding_model, texts)
|
|
384
384
|
except Exception as e:
|
|
385
|
-
PrettyOutput.print(f"
|
|
385
|
+
PrettyOutput.print(f"批量处理失败: {str(e)}", OutputType.ERROR)
|
|
386
386
|
return np.zeros((0, self.vector_dim), dtype=np.float32) # type: ignore
|
|
387
387
|
|
|
388
388
|
def _process_file(self, file_path: str) -> List[Document]:
|
|
@@ -436,7 +436,7 @@ class RAGTool:
|
|
|
436
436
|
return documents
|
|
437
437
|
|
|
438
438
|
except Exception as e:
|
|
439
|
-
PrettyOutput.print(f"
|
|
439
|
+
PrettyOutput.print(f"处理文件失败: {file_path}: {str(e)}",
|
|
440
440
|
output_type=OutputType.ERROR)
|
|
441
441
|
return []
|
|
442
442
|
|
|
@@ -517,7 +517,7 @@ class RAGTool:
|
|
|
517
517
|
new_vectors.append(file_vectors)
|
|
518
518
|
|
|
519
519
|
except Exception as e:
|
|
520
|
-
PrettyOutput.print(f"
|
|
520
|
+
PrettyOutput.print(f"处理文件失败: {file_path}: {str(e)}", OutputType.ERROR)
|
|
521
521
|
|
|
522
522
|
pbar.update(1)
|
|
523
523
|
|
|
@@ -542,9 +542,9 @@ class RAGTool:
|
|
|
542
542
|
self._build_index(final_vectors)
|
|
543
543
|
|
|
544
544
|
PrettyOutput.print(
|
|
545
|
-
f"
|
|
546
|
-
f"(
|
|
547
|
-
f"
|
|
545
|
+
f"索引 {len(self.documents)} 个文档 "
|
|
546
|
+
f"(新/修改: {len(new_documents)}, "
|
|
547
|
+
f"不变: {len(unchanged_documents)})",
|
|
548
548
|
OutputType.SUCCESS
|
|
549
549
|
)
|
|
550
550
|
|
|
@@ -566,13 +566,13 @@ class RAGTool:
|
|
|
566
566
|
return np.vstack(unchanged_vectors) if unchanged_vectors else None
|
|
567
567
|
|
|
568
568
|
except Exception as e:
|
|
569
|
-
PrettyOutput.print(f"
|
|
569
|
+
PrettyOutput.print(f"获取不变向量失败: {str(e)}", OutputType.ERROR)
|
|
570
570
|
return None
|
|
571
571
|
|
|
572
572
|
def search(self, query: str, top_k: int = 30) -> List[Tuple[Document, float]]:
|
|
573
573
|
"""Search documents with context window"""
|
|
574
574
|
if not self.index:
|
|
575
|
-
PrettyOutput.print("
|
|
575
|
+
PrettyOutput.print("索引未构建,正在构建...", output_type=OutputType.INFO)
|
|
576
576
|
self.build_index(self.root_dir)
|
|
577
577
|
|
|
578
578
|
# Get query vector
|
|
@@ -670,7 +670,7 @@ Relevant documents (ordered by relevance):
|
|
|
670
670
|
prompt += "3. Reference the documents in the answer.\n"
|
|
671
671
|
if current_count + get_context_token_count(doc_content) > available_count:
|
|
672
672
|
PrettyOutput.print(
|
|
673
|
-
"
|
|
673
|
+
"由于上下文长度限制,部分内容被省略",
|
|
674
674
|
output_type=OutputType.WARNING
|
|
675
675
|
)
|
|
676
676
|
break
|
|
@@ -687,7 +687,7 @@ Relevant documents (ordered by relevance):
|
|
|
687
687
|
return response
|
|
688
688
|
|
|
689
689
|
except Exception as e:
|
|
690
|
-
PrettyOutput.print(f"
|
|
690
|
+
PrettyOutput.print(f"回答失败:{str(e)}", OutputType.ERROR)
|
|
691
691
|
return None
|
|
692
692
|
|
|
693
693
|
def is_index_built(self) -> bool:
|
|
@@ -724,7 +724,7 @@ def main():
|
|
|
724
724
|
args.dir = current_dir
|
|
725
725
|
|
|
726
726
|
if args.dir and args.build:
|
|
727
|
-
PrettyOutput.print(f"
|
|
727
|
+
PrettyOutput.print(f"正在处理目录: {args.dir}", output_type=OutputType.INFO)
|
|
728
728
|
rag.build_index(args.dir)
|
|
729
729
|
return 0
|
|
730
730
|
|
|
@@ -733,13 +733,13 @@ def main():
|
|
|
733
733
|
if args.search:
|
|
734
734
|
results = rag.query(args.search)
|
|
735
735
|
if not results:
|
|
736
|
-
PrettyOutput.print("
|
|
736
|
+
PrettyOutput.print("未找到相关内容", output_type=OutputType.WARNING)
|
|
737
737
|
return 1
|
|
738
738
|
|
|
739
739
|
for doc in results:
|
|
740
|
-
output = f"""
|
|
741
|
-
output += f"""
|
|
742
|
-
output += f"""
|
|
740
|
+
output = f"""文件: {doc.metadata['file_path']}\n"""
|
|
741
|
+
output += f"""片段 {doc.metadata['chunk_index'] + 1}/{doc.metadata['total_chunks']}\n"""
|
|
742
|
+
output += f"""内容:\n{doc.content}\n"""
|
|
743
743
|
PrettyOutput.print(output, output_type=OutputType.INFO, lang="markdown")
|
|
744
744
|
return 0
|
|
745
745
|
|
|
@@ -747,19 +747,19 @@ def main():
|
|
|
747
747
|
# Call ask method
|
|
748
748
|
response = rag.ask(args.ask)
|
|
749
749
|
if not response:
|
|
750
|
-
PrettyOutput.print("
|
|
750
|
+
PrettyOutput.print("获取答案失败", output_type=OutputType.WARNING)
|
|
751
751
|
return 1
|
|
752
752
|
|
|
753
753
|
# Display answer
|
|
754
|
-
output = f"""
|
|
754
|
+
output = f"""答案:\n{response}"""
|
|
755
755
|
PrettyOutput.print(output, output_type=OutputType.INFO)
|
|
756
756
|
return 0
|
|
757
757
|
|
|
758
|
-
PrettyOutput.print("
|
|
758
|
+
PrettyOutput.print("请指定操作参数。使用 -h 查看帮助。", output_type=OutputType.WARNING)
|
|
759
759
|
return 1
|
|
760
760
|
|
|
761
761
|
except Exception as e:
|
|
762
|
-
PrettyOutput.print(f"
|
|
762
|
+
PrettyOutput.print(f"执行失败: {str(e)}", output_type=OutputType.ERROR)
|
|
763
763
|
return 1
|
|
764
764
|
|
|
765
765
|
if __name__ == "__main__":
|
|
@@ -13,7 +13,7 @@ from jarvis.utils import PrettyOutput, OutputType, get_shell_name, init_env
|
|
|
13
13
|
def execute_command(command: str) -> None:
|
|
14
14
|
"""Show command and allow user to edit, then execute, Ctrl+C to cancel"""
|
|
15
15
|
try:
|
|
16
|
-
print("
|
|
16
|
+
print("生成的命令 (可以编辑, 按回车执行, Ctrl+C 取消):")
|
|
17
17
|
# Pre-fill input line
|
|
18
18
|
readline.set_startup_hook(lambda: readline.insert_text(command))
|
|
19
19
|
try:
|
|
@@ -21,11 +21,11 @@ def execute_command(command: str) -> None:
|
|
|
21
21
|
if edited_command.strip(): # Ensure command is not empty
|
|
22
22
|
os.system(edited_command)
|
|
23
23
|
except KeyboardInterrupt:
|
|
24
|
-
print("
|
|
24
|
+
PrettyOutput.print("执行取消", OutputType.INFO)
|
|
25
25
|
finally:
|
|
26
26
|
readline.set_startup_hook() # Clear pre-filled
|
|
27
27
|
except Exception as e:
|
|
28
|
-
PrettyOutput.print(f"
|
|
28
|
+
PrettyOutput.print(f"执行命令失败: {str(e)}", OutputType.WARNING)
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def process_request(request: str) -> Optional[str]:
|
|
@@ -85,14 +85,14 @@ Remember: Only return the command itself, without any additional content.
|
|
|
85
85
|
return None
|
|
86
86
|
|
|
87
87
|
except Exception as e:
|
|
88
|
-
PrettyOutput.print(f"
|
|
88
|
+
PrettyOutput.print(f"处理请求失败: {str(e)}", OutputType.WARNING)
|
|
89
89
|
return None
|
|
90
90
|
|
|
91
91
|
def main():
|
|
92
92
|
# 创建参数解析器
|
|
93
93
|
init_env()
|
|
94
94
|
parser = argparse.ArgumentParser(
|
|
95
|
-
description="
|
|
95
|
+
description="将自然语言要求转换为shell命令",
|
|
96
96
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
97
97
|
epilog="""
|
|
98
98
|
Example:
|
|
@@ -104,7 +104,7 @@ Example:
|
|
|
104
104
|
# 添加参数
|
|
105
105
|
parser.add_argument(
|
|
106
106
|
"request",
|
|
107
|
-
help="
|
|
107
|
+
help="描述您想要执行的操作, 用自然语言描述"
|
|
108
108
|
)
|
|
109
109
|
|
|
110
110
|
# 解析参数
|
|
@@ -45,7 +45,7 @@ class AskCodebaseTool:
|
|
|
45
45
|
question = args["question"]
|
|
46
46
|
top_k = args.get("top_k", 20)
|
|
47
47
|
|
|
48
|
-
PrettyOutput.print(f"
|
|
48
|
+
PrettyOutput.print(f"正在分析代码库以回答问题: {question}", OutputType.INFO)
|
|
49
49
|
|
|
50
50
|
# Create new CodeBase instance
|
|
51
51
|
git_root = find_git_root()
|
|
@@ -61,8 +61,8 @@ class AskCodebaseTool:
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
except Exception as e:
|
|
64
|
-
error_msg = f"
|
|
65
|
-
PrettyOutput.print(error_msg, OutputType.
|
|
64
|
+
error_msg = f"分析代码库失败: {str(e)}"
|
|
65
|
+
PrettyOutput.print(error_msg, OutputType.WARNING)
|
|
66
66
|
return {
|
|
67
67
|
"success": False,
|
|
68
68
|
"stdout": "",
|
jarvis/jarvis_tools/ask_user.py
CHANGED
|
@@ -30,10 +30,10 @@ class AskUserTool:
|
|
|
30
30
|
question = args["question"]
|
|
31
31
|
|
|
32
32
|
# Display the question
|
|
33
|
-
PrettyOutput.print(f"
|
|
33
|
+
PrettyOutput.print(f"问题: {question}", OutputType.SYSTEM)
|
|
34
34
|
|
|
35
35
|
# Get user input
|
|
36
|
-
user_response = get_multiline_input("
|
|
36
|
+
user_response = get_multiline_input("请输入您的答案 (输入空行结束)")
|
|
37
37
|
|
|
38
38
|
return {
|
|
39
39
|
"success": True,
|
|
@@ -31,7 +31,7 @@ class CreateCodeAgentTool:
|
|
|
31
31
|
# Step 1: Handle uncommitted changes
|
|
32
32
|
start_commit = None
|
|
33
33
|
if has_uncommitted_changes():
|
|
34
|
-
PrettyOutput.print("
|
|
34
|
+
PrettyOutput.print("发现未提交的更改,正在提交...", OutputType.INFO)
|
|
35
35
|
git_commiter = GitCommitTool()
|
|
36
36
|
result = git_commiter.execute({})
|
|
37
37
|
if not result["success"]:
|
|
@@ -45,7 +45,7 @@ class CreateCodeAgentTool:
|
|
|
45
45
|
start_commit = self._get_current_commit()
|
|
46
46
|
|
|
47
47
|
# Step 2: Development
|
|
48
|
-
PrettyOutput.print("
|
|
48
|
+
PrettyOutput.print("开始开发...", OutputType.INFO)
|
|
49
49
|
agent = CodeAgent()
|
|
50
50
|
agent.run(requirement)
|
|
51
51
|
|
|
@@ -53,7 +53,7 @@ class CreateCodeAgentTool:
|
|
|
53
53
|
end_commit = self._get_current_commit()
|
|
54
54
|
|
|
55
55
|
# Step 3: Code Review
|
|
56
|
-
PrettyOutput.print("
|
|
56
|
+
PrettyOutput.print("开始代码审查...", OutputType.INFO)
|
|
57
57
|
reviewer = CodeReviewTool()
|
|
58
58
|
review_result = reviewer.execute({
|
|
59
59
|
"review_type": "range",
|
|
@@ -69,15 +69,15 @@ class CreateCodeAgentTool:
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
# Step 4: Generate Summary
|
|
72
|
-
summary = f"""
|
|
72
|
+
summary = f"""开发总结:
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
开始提交: {start_commit}
|
|
75
|
+
结束提交: {end_commit}
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
需求:
|
|
78
78
|
{requirement}
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
代码审查结果:
|
|
81
81
|
{extract_code_report(review_result["stdout"])}
|
|
82
82
|
"""
|
|
83
83
|
|
|
@@ -50,7 +50,7 @@ class SubAgentTool:
|
|
|
50
50
|
goal = args.get("goal", "")
|
|
51
51
|
files = args.get("files", [])
|
|
52
52
|
|
|
53
|
-
PrettyOutput.print(f"
|
|
53
|
+
PrettyOutput.print(f"创建子代理: {agent_name}", OutputType.INFO)
|
|
54
54
|
|
|
55
55
|
# Build task description
|
|
56
56
|
task_description = task
|
|
@@ -68,7 +68,7 @@ class SubAgentTool:
|
|
|
68
68
|
)
|
|
69
69
|
|
|
70
70
|
# Run sub-agent, pass file list
|
|
71
|
-
PrettyOutput.print("
|
|
71
|
+
PrettyOutput.print("子代理开始执行任务...", OutputType.INFO)
|
|
72
72
|
result = sub_agent.run(task_description, file_list=files)
|
|
73
73
|
|
|
74
74
|
return {
|
|
@@ -40,7 +40,7 @@ class ShellTool:
|
|
|
40
40
|
# Modify command to use script
|
|
41
41
|
tee_command = f"script -q -c '{escaped_command}' {output_file}"
|
|
42
42
|
|
|
43
|
-
PrettyOutput.print(f"
|
|
43
|
+
PrettyOutput.print(f"执行命令: {command}", OutputType.INFO)
|
|
44
44
|
|
|
45
45
|
# Execute command
|
|
46
46
|
return_code = os.system(tee_command)
|
|
@@ -55,7 +55,7 @@ class ShellTool:
|
|
|
55
55
|
if len(lines) > 2:
|
|
56
56
|
output = "\n".join(lines[1:-1])
|
|
57
57
|
except Exception as e:
|
|
58
|
-
output = f"
|
|
58
|
+
output = f"读取输出文件失败: {str(e)}"
|
|
59
59
|
finally:
|
|
60
60
|
# Clean up temporary file
|
|
61
61
|
Path(output_file).unlink(missing_ok=True)
|
|
@@ -43,7 +43,7 @@ class FileOperationTool:
|
|
|
43
43
|
|
|
44
44
|
# Record the operation and the full path
|
|
45
45
|
abs_path = os.path.abspath(filepath)
|
|
46
|
-
PrettyOutput.print(f"
|
|
46
|
+
PrettyOutput.print(f"文件操作: {operation} - {abs_path}", OutputType.INFO)
|
|
47
47
|
|
|
48
48
|
if operation == "exists":
|
|
49
49
|
exists = os.path.exists(filepath)
|
|
@@ -4,7 +4,7 @@ from typing import Dict, Any
|
|
|
4
4
|
|
|
5
5
|
import yaml
|
|
6
6
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
7
|
-
from jarvis.utils import OutputType, PrettyOutput, init_env
|
|
7
|
+
from jarvis.utils import OutputType, PrettyOutput, has_uncommitted_changes, init_env
|
|
8
8
|
import sys
|
|
9
9
|
|
|
10
10
|
|
|
@@ -25,7 +25,10 @@ class GitCommitTool:
|
|
|
25
25
|
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
26
26
|
"""Execute automatic commit process"""
|
|
27
27
|
try:
|
|
28
|
-
|
|
28
|
+
if not has_uncommitted_changes():
|
|
29
|
+
PrettyOutput.print("没有未提交的更改", OutputType.SUCCESS)
|
|
30
|
+
return {"success": True, "stdout": "No uncommitted changes", "stderr": ""}
|
|
31
|
+
PrettyOutput.print("准备添加文件到提交...", OutputType.SYSTEM)
|
|
29
32
|
os.system("git add .")
|
|
30
33
|
PrettyOutput.print("Get diff...", OutputType.SYSTEM)
|
|
31
34
|
diff = os.popen("git diff --cached --exit-code").read()
|
|
@@ -40,17 +43,17 @@ class GitCommitTool:
|
|
|
40
43
|
|
|
41
44
|
{diff}
|
|
42
45
|
'''
|
|
43
|
-
PrettyOutput.print("
|
|
46
|
+
PrettyOutput.print("生成提交消息...", OutputType.SYSTEM)
|
|
44
47
|
platform = PlatformRegistry().get_codegen_platform()
|
|
45
48
|
platform.set_suppress_output(True)
|
|
46
49
|
commit_message = platform.chat_until_success(prompt)
|
|
47
50
|
commit_message = self._extract_commit_message(commit_message)
|
|
48
|
-
PrettyOutput.print("
|
|
51
|
+
PrettyOutput.print("提交...", OutputType.INFO)
|
|
49
52
|
os.popen(f"git commit -m '{commit_message}'")
|
|
50
53
|
|
|
51
54
|
commit_hash = self._get_last_commit_hash()
|
|
52
55
|
|
|
53
|
-
PrettyOutput.section(f"
|
|
56
|
+
PrettyOutput.section(f"提交哈希: {commit_hash}\n提交消息: {commit_message}", OutputType.SUCCESS)
|
|
54
57
|
|
|
55
58
|
return {"success": True, "stdout": yaml.safe_dump({"commit_hash": commit_hash, "commit_message": commit_message}), "stderr": ""}
|
|
56
59
|
|
|
@@ -47,7 +47,7 @@ class MethodologyTool:
|
|
|
47
47
|
with open(self.methodology_file, 'w', encoding='utf-8') as f:
|
|
48
48
|
yaml.safe_dump({}, f, allow_unicode=True)
|
|
49
49
|
except Exception as e:
|
|
50
|
-
PrettyOutput.print(f"
|
|
50
|
+
PrettyOutput.print(f"创建方法论文件失败:{str(e)}", OutputType.ERROR)
|
|
51
51
|
|
|
52
52
|
def _load_methodologies(self) -> Dict:
|
|
53
53
|
"""Load all methodologies"""
|
|
@@ -55,7 +55,7 @@ class MethodologyTool:
|
|
|
55
55
|
with open(self.methodology_file, 'r', encoding='utf-8') as f:
|
|
56
56
|
return yaml.safe_load(f) or {}
|
|
57
57
|
except Exception as e:
|
|
58
|
-
PrettyOutput.print(f"
|
|
58
|
+
PrettyOutput.print(f"加载方法论失败: {str(e)}", OutputType.ERROR)
|
|
59
59
|
return {}
|
|
60
60
|
|
|
61
61
|
def _save_methodologies(self, methodologies: Dict):
|
|
@@ -64,7 +64,7 @@ class MethodologyTool:
|
|
|
64
64
|
with open(self.methodology_file, 'w', encoding='utf-8') as f:
|
|
65
65
|
yaml.safe_dump(methodologies, f, allow_unicode=True)
|
|
66
66
|
except Exception as e:
|
|
67
|
-
PrettyOutput.print(f"
|
|
67
|
+
PrettyOutput.print(f"保存方法论失败: {str(e)}", OutputType.ERROR)
|
|
68
68
|
|
|
69
69
|
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
70
70
|
"""Execute the operation of managing methodologies
|
jarvis/jarvis_tools/rag.py
CHANGED
|
@@ -87,11 +87,11 @@ class RAGTool:
|
|
|
87
87
|
|
|
88
88
|
# If you need to rebuild the index or the index does not exist
|
|
89
89
|
if rebuild_index or not rag.is_index_built():
|
|
90
|
-
PrettyOutput.print("
|
|
90
|
+
PrettyOutput.print("正在构建文档索引...", OutputType.INFO)
|
|
91
91
|
rag.build_index(dir_path)
|
|
92
92
|
|
|
93
93
|
# Execute question and answer
|
|
94
|
-
PrettyOutput.print(f"
|
|
94
|
+
PrettyOutput.print(f"问题: {question}", OutputType.INFO)
|
|
95
95
|
response = rag.ask(question)
|
|
96
96
|
|
|
97
97
|
if response is None:
|
|
@@ -108,7 +108,7 @@ class RAGTool:
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
except Exception as e:
|
|
111
|
-
PrettyOutput.print(f"
|
|
111
|
+
PrettyOutput.print(f"文档问答失败:{str(e)}", OutputType.ERROR)
|
|
112
112
|
return {
|
|
113
113
|
"success": False,
|
|
114
114
|
"stdout": "",
|
jarvis/jarvis_tools/read_code.py
CHANGED
|
@@ -51,7 +51,7 @@ class ReadCodeTool:
|
|
|
51
51
|
|
|
52
52
|
# Record the operation and the full path
|
|
53
53
|
abs_path = os.path.abspath(filepath)
|
|
54
|
-
PrettyOutput.print(f"
|
|
54
|
+
PrettyOutput.print(f"正在读取代码文件:{abs_path}", OutputType.INFO)
|
|
55
55
|
|
|
56
56
|
# Check if file exists
|
|
57
57
|
if not os.path.exists(filepath):
|
|
@@ -5,7 +5,7 @@ from jarvis.utils import PrettyOutput, OutputType
|
|
|
5
5
|
|
|
6
6
|
class WebpageTool:
|
|
7
7
|
name = "read_webpage"
|
|
8
|
-
description = "Read webpage content, extract title and
|
|
8
|
+
description = "Read webpage content, extract title, text and hyperlinks"
|
|
9
9
|
parameters = {
|
|
10
10
|
"type": "object",
|
|
11
11
|
"properties": {
|
|
@@ -28,7 +28,7 @@ class WebpageTool:
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
# Send request
|
|
31
|
-
PrettyOutput.print(f"
|
|
31
|
+
PrettyOutput.print(f"正在读取网页:{url}", OutputType.INFO)
|
|
32
32
|
response = requests.get(url, headers=headers, timeout=10)
|
|
33
33
|
response.raise_for_status()
|
|
34
34
|
|
|
@@ -46,16 +46,29 @@ class WebpageTool:
|
|
|
46
46
|
title = soup.title.string if soup.title else ""
|
|
47
47
|
title = title.strip() if title else "No title"
|
|
48
48
|
|
|
49
|
-
# Extract text
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
# Extract text and links
|
|
50
|
+
text_parts = []
|
|
51
|
+
links = []
|
|
52
|
+
|
|
53
|
+
# Process content and collect links
|
|
54
|
+
for element in soup.descendants:
|
|
55
|
+
if element.name == 'a' and element.get('href'): # type: ignore
|
|
56
|
+
href = element.get('href') # type: ignore
|
|
57
|
+
text = element.get_text(strip=True)
|
|
58
|
+
if text and href:
|
|
59
|
+
links.append(f"[{text}]({href})")
|
|
60
|
+
elif isinstance(element, str) and element.strip():
|
|
61
|
+
text_parts.append(element.strip())
|
|
52
62
|
|
|
53
63
|
# Build output
|
|
54
64
|
output = [
|
|
55
65
|
f"Title: {title}",
|
|
56
66
|
"",
|
|
57
67
|
"Text content:",
|
|
58
|
-
"\n".join(
|
|
68
|
+
"\n".join(text_parts),
|
|
69
|
+
"",
|
|
70
|
+
"Links found:",
|
|
71
|
+
"\n".join(links) if links else "No links found"
|
|
59
72
|
]
|
|
60
73
|
|
|
61
74
|
return {
|
jarvis/jarvis_tools/registry.py
CHANGED
|
@@ -71,7 +71,7 @@ class ToolRegistry:
|
|
|
71
71
|
"""Use specified tools"""
|
|
72
72
|
missing_tools = [tool_name for tool_name in name if tool_name not in self.tools]
|
|
73
73
|
if missing_tools:
|
|
74
|
-
PrettyOutput.print(f"
|
|
74
|
+
PrettyOutput.print(f"工具 {missing_tools} 不存在,可用的工具有: {', '.join(self.tools.keys())}", OutputType.WARNING)
|
|
75
75
|
self.tools = {tool_name: self.tools[tool_name] for tool_name in name}
|
|
76
76
|
|
|
77
77
|
def dont_use_tools(self, names: List[str]):
|
|
@@ -116,7 +116,7 @@ class ToolRegistry:
|
|
|
116
116
|
try:
|
|
117
117
|
p_file_path = Path(file_path).resolve() # Get the absolute path
|
|
118
118
|
if not p_file_path.exists() or not p_file_path.is_file():
|
|
119
|
-
PrettyOutput.print(f"
|
|
119
|
+
PrettyOutput.print(f"文件不存在: {p_file_path}", OutputType.ERROR)
|
|
120
120
|
return False
|
|
121
121
|
|
|
122
122
|
# Add the parent directory to sys.path temporarily
|
|
@@ -167,7 +167,7 @@ class ToolRegistry:
|
|
|
167
167
|
sys.path.remove(parent_dir)
|
|
168
168
|
|
|
169
169
|
except Exception as e:
|
|
170
|
-
PrettyOutput.print(f"
|
|
170
|
+
PrettyOutput.print(f"从 {Path(file_path).name} 加载工具失败: {str(e)}", OutputType.ERROR)
|
|
171
171
|
return False
|
|
172
172
|
|
|
173
173
|
def register_tool(self, name: str, description: str, parameters: Dict, func: Callable):
|
|
@@ -215,12 +215,12 @@ arguments:
|
|
|
215
215
|
try:
|
|
216
216
|
args = json.loads(args)
|
|
217
217
|
except json.JSONDecodeError:
|
|
218
|
-
PrettyOutput.print(f"
|
|
218
|
+
PrettyOutput.print(f"工具参数格式无效: {name} {tool_call_help}", OutputType.ERROR)
|
|
219
219
|
return ""
|
|
220
220
|
|
|
221
221
|
# Display tool call information
|
|
222
|
-
PrettyOutput.section(f"
|
|
223
|
-
params = "
|
|
222
|
+
PrettyOutput.section(f"执行工具: {name}", OutputType.TOOL)
|
|
223
|
+
params = "参数:\n"
|
|
224
224
|
if isinstance(args, dict):
|
|
225
225
|
for key, value in args.items():
|
|
226
226
|
params += f"{key} = {value}\n"
|
|
@@ -245,12 +245,12 @@ arguments:
|
|
|
245
245
|
# Process the result
|
|
246
246
|
if result["success"]:
|
|
247
247
|
|
|
248
|
-
PrettyOutput.section("
|
|
248
|
+
PrettyOutput.section("执行成功", OutputType.SUCCESS)
|
|
249
249
|
|
|
250
250
|
# If the output exceeds 4k characters, use a large model to summarize
|
|
251
251
|
if get_context_token_count(output) > self.max_token_count:
|
|
252
252
|
try:
|
|
253
|
-
PrettyOutput.print("
|
|
253
|
+
PrettyOutput.print("输出过长,正在总结...", OutputType.PROGRESS)
|
|
254
254
|
model = PlatformRegistry.get_global_platform_registry().get_normal_platform()
|
|
255
255
|
|
|
256
256
|
# If the output exceeds the maximum context length, only take the last part
|
|
@@ -282,11 +282,11 @@ Please provide a summary:"""
|
|
|
282
282
|
--- Summary ends ---"""
|
|
283
283
|
|
|
284
284
|
except Exception as e:
|
|
285
|
-
PrettyOutput.print(f"
|
|
285
|
+
PrettyOutput.print(f"总结失败: {str(e)}", OutputType.ERROR)
|
|
286
286
|
output = f"Output is too long ({len(output)} characters), it is recommended to view the original output.\nPreview of the first 300 characters:\n{output[:300]}..."
|
|
287
287
|
|
|
288
288
|
else:
|
|
289
|
-
PrettyOutput.section("
|
|
289
|
+
PrettyOutput.section("执行失败", OutputType.WARNING)
|
|
290
290
|
PrettyOutput.print(result["stderr"], OutputType.WARNING)
|
|
291
291
|
|
|
292
292
|
if len(tool_calls) > 1:
|
|
@@ -294,5 +294,5 @@ Please provide a summary:"""
|
|
|
294
294
|
return output
|
|
295
295
|
|
|
296
296
|
except Exception as e:
|
|
297
|
-
PrettyOutput.print(f"
|
|
297
|
+
PrettyOutput.print(f"工具执行失败:{str(e)}", OutputType.ERROR)
|
|
298
298
|
return f"Tool call failed: {str(e)}"
|