jarvis-ai-assistant 0.1.186__py3-none-any.whl → 0.1.188__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.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +9 -11
- jarvis/jarvis_agent/file_input_handler.py +22 -22
- jarvis/jarvis_agent/main.py +10 -11
- jarvis/jarvis_git_utils/git_commiter.py +1 -2
- jarvis/jarvis_tools/edit_file.py +20 -3
- {jarvis_ai_assistant-0.1.186.dist-info → jarvis_ai_assistant-0.1.188.dist-info}/METADATA +1 -1
- {jarvis_ai_assistant-0.1.186.dist-info → jarvis_ai_assistant-0.1.188.dist-info}/RECORD +12 -12
- {jarvis_ai_assistant-0.1.186.dist-info → jarvis_ai_assistant-0.1.188.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.186.dist-info → jarvis_ai_assistant-0.1.188.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.186.dist-info → jarvis_ai_assistant-0.1.188.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.186.dist-info → jarvis_ai_assistant-0.1.188.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
@@ -436,7 +436,9 @@ class Agent:
|
|
436
436
|
if self.conversation_length > self.max_token_count:
|
437
437
|
message = self._summarize_and_clear_history() + "\n\n" + message
|
438
438
|
self.conversation_length += get_context_token_count(message)
|
439
|
-
|
439
|
+
response = self.model.chat_until_success(message) # type: ignore
|
440
|
+
self.conversation_length += get_context_token_count(response)
|
441
|
+
return response
|
440
442
|
|
441
443
|
def _summarize_and_clear_history(self) -> str:
|
442
444
|
"""总结当前对话并清理历史记录
|
@@ -771,36 +773,32 @@ arguments:
|
|
771
773
|
try:
|
772
774
|
set_agent(self.name, self)
|
773
775
|
|
774
|
-
for handler in self.input_handler:
|
775
|
-
user_input, _ = handler(user_input, self)
|
776
|
-
|
777
776
|
self.prompt = f"{user_input}"
|
778
777
|
|
779
778
|
if self.first:
|
780
779
|
# 如果有上传文件,先上传文件
|
781
780
|
if self.files and isinstance(self.model, BasePlatform) and hasattr(self.model, "upload_files"):
|
782
781
|
self.model.upload_files(self.files)
|
783
|
-
self.prompt = f"{user_input}
|
782
|
+
self.prompt = f"{user_input}"
|
784
783
|
|
785
784
|
# 如果启用方法论且没有上传文件,上传方法论
|
786
785
|
elif self.use_methodology:
|
787
786
|
platform = self.model if hasattr(self.model, "upload_files") else None
|
788
787
|
if platform and upload_methodology(platform):
|
789
|
-
self.prompt = f"{user_input}
|
788
|
+
self.prompt = f"{user_input}"
|
790
789
|
else:
|
791
790
|
# 上传失败则回退到本地加载
|
792
|
-
|
791
|
+
msg = user_input
|
792
|
+
for handler in self.input_handler:
|
793
|
+
msg, _ = handler(msg, self)
|
794
|
+
self.prompt = f"{user_input}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
|
793
795
|
|
794
796
|
self.first = False
|
795
797
|
|
796
|
-
self.conversation_length = get_context_token_count(self.prompt)
|
797
798
|
while True:
|
798
799
|
try:
|
799
800
|
current_response = self._call_model(self.prompt, True)
|
800
801
|
self.prompt = ""
|
801
|
-
self.conversation_length += get_context_token_count(
|
802
|
-
current_response
|
803
|
-
)
|
804
802
|
|
805
803
|
need_return, self.prompt = self._call_tools(current_response)
|
806
804
|
|
@@ -13,69 +13,69 @@ from jarvis.jarvis_utils.utils import is_context_overflow
|
|
13
13
|
|
14
14
|
|
15
15
|
def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
|
16
|
-
"""
|
16
|
+
"""处理包含文件引用的用户输入并读取文件内容。
|
17
17
|
|
18
|
-
|
19
|
-
user_input:
|
20
|
-
- 'file_path' (
|
21
|
-
- 'file_path:start_line,end_line' (
|
22
|
-
- 'file_path:start_line:end_line' (
|
23
|
-
agent: Agent
|
18
|
+
参数:
|
19
|
+
user_input: 可能包含文件引用的输入字符串,格式为:
|
20
|
+
- 'file_path' (整个文件)
|
21
|
+
- 'file_path:start_line,end_line' (行范围)
|
22
|
+
- 'file_path:start_line:end_line' (替代范围格式)
|
23
|
+
agent: 用于进一步处理的Agent对象(当前未使用)
|
24
24
|
|
25
|
-
|
25
|
+
返回:
|
26
26
|
Tuple[str, bool]:
|
27
|
-
-
|
28
|
-
-
|
27
|
+
- 处理后的提示字符串,前面附加文件内容
|
28
|
+
- 布尔值,指示是否发生上下文溢出
|
29
29
|
"""
|
30
30
|
prompt = user_input
|
31
31
|
files = []
|
32
32
|
|
33
|
-
file_refs = re.findall(r"'([^']+)'", user_input)
|
33
|
+
file_refs = re.findall(r"'([^'\n]+)'", user_input)
|
34
34
|
for ref in file_refs:
|
35
|
-
#
|
35
|
+
# 处理 file:start,end 或 file:start:end 格式
|
36
36
|
if ':' in ref:
|
37
37
|
file_path, line_range = ref.split(':', 1)
|
38
|
-
#
|
38
|
+
# 使用默认值初始化
|
39
39
|
start_line = 1 # 1-based
|
40
40
|
end_line = -1
|
41
41
|
|
42
|
-
#
|
42
|
+
# 如果指定了行范围则进行处理
|
43
43
|
if ',' in line_range or ':' in line_range:
|
44
44
|
try:
|
45
45
|
raw_start, raw_end = map(int, re.split(r'[,:]', line_range))
|
46
46
|
|
47
|
-
#
|
47
|
+
# 处理特殊值和Python风格的负索引
|
48
48
|
try:
|
49
49
|
with open(file_path, 'r', encoding='utf-8', errors="ignore") as f:
|
50
50
|
total_lines = len(f.readlines())
|
51
51
|
except FileNotFoundError:
|
52
52
|
PrettyOutput.print(f"文件不存在: {file_path}", OutputType.WARNING)
|
53
53
|
continue
|
54
|
-
#
|
54
|
+
# 处理起始行(0表示整个文件,负数表示从末尾开始)
|
55
55
|
if raw_start == 0: # 0表示整个文件
|
56
56
|
start_line = 1
|
57
57
|
end_line = total_lines
|
58
58
|
else:
|
59
59
|
start_line = raw_start if raw_start > 0 else total_lines + raw_start + 1
|
60
60
|
|
61
|
-
#
|
61
|
+
# 处理结束行
|
62
62
|
if raw_end == 0: # 0表示整个文件(如果start也是0)
|
63
63
|
end_line = total_lines
|
64
64
|
else:
|
65
65
|
end_line = raw_end if raw_end > 0 else total_lines + raw_end + 1
|
66
66
|
|
67
|
-
#
|
67
|
+
# 自动校正范围
|
68
68
|
start_line = max(1, min(start_line, total_lines))
|
69
69
|
end_line = max(start_line, min(end_line, total_lines))
|
70
70
|
|
71
|
-
#
|
71
|
+
# 最终验证
|
72
72
|
if start_line < 1 or end_line > total_lines or start_line > end_line:
|
73
73
|
raise ValueError
|
74
74
|
|
75
75
|
except:
|
76
76
|
continue
|
77
77
|
|
78
|
-
#
|
78
|
+
# 如果文件存在则添加
|
79
79
|
if os.path.isfile(file_path):
|
80
80
|
files.append({
|
81
81
|
"path": file_path,
|
@@ -83,7 +83,7 @@ def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
|
|
83
83
|
"end_line": end_line
|
84
84
|
})
|
85
85
|
else:
|
86
|
-
#
|
86
|
+
# 处理简单文件路径
|
87
87
|
if os.path.isfile(ref):
|
88
88
|
files.append({
|
89
89
|
"path": ref,
|
@@ -91,7 +91,7 @@ def file_input_handler(user_input: str, agent: Any) -> Tuple[str, bool]:
|
|
91
91
|
"end_line": -1
|
92
92
|
})
|
93
93
|
|
94
|
-
#
|
94
|
+
# 如果找到文件则读取并处理
|
95
95
|
if files:
|
96
96
|
with yaspin(text="正在读取文件...", color="cyan") as spinner:
|
97
97
|
old_prompt = prompt
|
jarvis/jarvis_agent/main.py
CHANGED
@@ -35,7 +35,7 @@ def main():
|
|
35
35
|
"""Main entry point for Jarvis agent"""
|
36
36
|
# Set up argument parser
|
37
37
|
parser = argparse.ArgumentParser(description='Jarvis AI assistant')
|
38
|
-
parser.add_argument('-f', '--config', type=str, required=
|
38
|
+
parser.add_argument('-f', '--config', type=str, required=False,
|
39
39
|
help='Path to agent config file')
|
40
40
|
parser.add_argument('-c', '--agent_definition', type=str,
|
41
41
|
help='Path to agent definition file')
|
@@ -59,16 +59,15 @@ def main():
|
|
59
59
|
agent.run(args.task)
|
60
60
|
return 0
|
61
61
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
|
62
|
+
|
63
|
+
try:
|
64
|
+
user_input = get_multiline_input("请输入你的任务(输入空行退出):")
|
65
|
+
if not user_input:
|
66
|
+
return 0
|
67
|
+
agent.set_addon_prompt("如果有必要,请先指定出行动计划,然后根据计划一步步执行,如果任务过于复杂,可以拆分子Agent进行执行,拆的子Agent需要掌握所有必要的任务信息,否则无法执行")
|
68
|
+
agent.run(user_input)
|
69
|
+
except Exception as e:
|
70
|
+
PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
|
72
71
|
|
73
72
|
except Exception as e:
|
74
73
|
PrettyOutput.print(f"初始化错误: {str(e)}", OutputType.ERROR)
|
@@ -2,7 +2,6 @@
|
|
2
2
|
import argparse
|
3
3
|
import os
|
4
4
|
import re
|
5
|
-
import shlex
|
6
5
|
import subprocess
|
7
6
|
import sys
|
8
7
|
import tempfile
|
@@ -53,7 +52,7 @@ class GitCommitTool:
|
|
53
52
|
)
|
54
53
|
if r:
|
55
54
|
# 直接返回原始内容,仅去除外围空白
|
56
|
-
return
|
55
|
+
return r.group(1).strip()
|
57
56
|
return None
|
58
57
|
|
59
58
|
def _get_last_commit_hash(self):
|
jarvis/jarvis_tools/edit_file.py
CHANGED
@@ -435,9 +435,26 @@ def fast_edit(filepath: str, patches: List[Dict[str,str]], spinner: Yaspin) -> T
|
|
435
435
|
search_text, replace_text)
|
436
436
|
spinner.write(f"✅ 补丁 #{patch_count} 应用成功")
|
437
437
|
else:
|
438
|
-
|
439
|
-
|
440
|
-
|
438
|
+
# 尝试增加缩进重试
|
439
|
+
found = False
|
440
|
+
for space_count in range(1, 17):
|
441
|
+
indented_search = '\n'.join(' ' * space_count + line for line in search_text.split('\n'))
|
442
|
+
indented_replace = '\n'.join(' ' * space_count + line for line in replace_text.split('\n'))
|
443
|
+
if indented_search in modified_content:
|
444
|
+
if modified_content.count(indented_search) > 1:
|
445
|
+
success = False
|
446
|
+
err_msg = f"搜索文本 {indented_search} 在文件中存在多处,请检查补丁内容"
|
447
|
+
break
|
448
|
+
modified_content = modified_content.replace(
|
449
|
+
indented_search, indented_replace)
|
450
|
+
spinner.write(f"✅ 补丁 #{patch_count} 应用成功 (自动增加 {space_count} 个空格缩进)")
|
451
|
+
found = True
|
452
|
+
break
|
453
|
+
|
454
|
+
if not found:
|
455
|
+
success = False
|
456
|
+
err_msg = f"搜索文本 {search_text} 在文件中不存在,尝试增加1-16个空格缩进后仍未找到匹配"
|
457
|
+
break
|
441
458
|
if not success:
|
442
459
|
revert_file(filepath)
|
443
460
|
return False, err_msg
|
@@ -1,9 +1,9 @@
|
|
1
|
-
jarvis/__init__.py,sha256=
|
2
|
-
jarvis/jarvis_agent/__init__.py,sha256=
|
1
|
+
jarvis/__init__.py,sha256=KuZvt3HQLtENkv0s1NLND9zxkPs9blE1UCYGe9GmPNw,74
|
2
|
+
jarvis/jarvis_agent/__init__.py,sha256=76gF2jieAQjP3M6YlDxx2dzaE2XD95nfAFRMySP-Azs,30654
|
3
3
|
jarvis/jarvis_agent/builtin_input_handler.py,sha256=f4DaEHPakXcAbgykFP-tiOQP6fh_yGFlZx_h91_j2tQ,1529
|
4
|
-
jarvis/jarvis_agent/file_input_handler.py,sha256=
|
4
|
+
jarvis/jarvis_agent/file_input_handler.py,sha256=OfoYI5on6w5BDUUg4OadFcfWzMsUF70GNrlt9QyauvA,4181
|
5
5
|
jarvis/jarvis_agent/jarvis.py,sha256=gOZfTwVlG-GZxPjgCoSiIcFsl4RwwfPA0CGUjE5J7oU,6249
|
6
|
-
jarvis/jarvis_agent/main.py,sha256=
|
6
|
+
jarvis/jarvis_agent/main.py,sha256=miR8wnWBzmbhOfnscyiKo1oI4wZBRU6FEE-k1lkqtiI,2752
|
7
7
|
jarvis/jarvis_agent/output_handler.py,sha256=7qori-RGrQmdiFepoEe3oPPKJIvRt90l_JDmvCoa4zA,1219
|
8
8
|
jarvis/jarvis_agent/shell_input_handler.py,sha256=pi3AtPKrkKc6K9e99S1djKXQ_XrxtP6FrSWebQmRT6E,1261
|
9
9
|
jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -38,7 +38,7 @@ jarvis/jarvis_git_details/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
38
38
|
jarvis/jarvis_git_details/main.py,sha256=MfR7feVVQ7Eo9eZk-wO2bFypnA6uRrYUQn6iTeoF0Os,9007
|
39
39
|
jarvis/jarvis_git_squash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
40
40
|
jarvis/jarvis_git_squash/main.py,sha256=q8-r0TtVOaCqY_uYwnWAY76k8YCDd5se_feB6ZWKo9M,2278
|
41
|
-
jarvis/jarvis_git_utils/git_commiter.py,sha256=
|
41
|
+
jarvis/jarvis_git_utils/git_commiter.py,sha256=S8fplYbw5Nl3tj-R6Qqn94MV1bJKX8VAJsBqUX5XAiY,12958
|
42
42
|
jarvis/jarvis_mcp/__init__.py,sha256=NF_vqRxaNyz8ColcpRh0bOkinV90YLAKHEN--jkP-B8,2114
|
43
43
|
jarvis/jarvis_mcp/sse_mcp_client.py,sha256=QNA7HqFvLbvhNaFp3ZsXzs2Rm6_gHUMcpd4t4qAzymY,23485
|
44
44
|
jarvis/jarvis_mcp/stdio_mcp_client.py,sha256=IEkas4ojP5J0TdVaUglvlEp61RyezBtuejv4lN3n1I4,11831
|
@@ -65,7 +65,7 @@ jarvis/jarvis_tools/chdir.py,sha256=DNKVFrWqu6t_sZ2ipv99s6802QR4cSGlqKlmaI--arE,
|
|
65
65
|
jarvis/jarvis_tools/code_plan.py,sha256=gWR0lzY62x2PxWKoMRBqW6jq7zQuO8vhpjC4TcHSYjk,7685
|
66
66
|
jarvis/jarvis_tools/create_code_agent.py,sha256=-nHfo5O5pDIG5IX3w1ClQafGvGcdI2_w75-KGrD-gUQ,3458
|
67
67
|
jarvis/jarvis_tools/create_sub_agent.py,sha256=lyFrrg4V0yXULmU3vldwGp_euZjwZzJcRU6mJ20zejY,3023
|
68
|
-
jarvis/jarvis_tools/edit_file.py,sha256=
|
68
|
+
jarvis/jarvis_tools/edit_file.py,sha256=lI6x2Vf7wrF-WdZN9qsmuiSm8jAUSyGSTk1mlGXq9FQ,18369
|
69
69
|
jarvis/jarvis_tools/execute_script.py,sha256=IA1SkcnwBB9PKG2voBNx5N9GXL303OC7OOtdqRfqWOk,6428
|
70
70
|
jarvis/jarvis_tools/file_analyzer.py,sha256=7ILHkUFm8pPZn1y_s4uT0kaWHP-EmlHnpkovDdA1yRE,4872
|
71
71
|
jarvis/jarvis_tools/file_operation.py,sha256=WloC1-oPJLwgICu4WBc9f7XA8N_Ggl73QQ5CxM2XTlE,9464
|
@@ -91,9 +91,9 @@ jarvis/jarvis_utils/methodology.py,sha256=A8pE8ZqNHvGKaDO4TFtg7Oz-hAXPBcQfhmSPWM
|
|
91
91
|
jarvis/jarvis_utils/output.py,sha256=QboL42GtG_dnvd1O64sl8o72mEBhXNRADPXQMXgDE7Q,9661
|
92
92
|
jarvis/jarvis_utils/tag.py,sha256=YJHmuedLb7_AiqvKQetHr4R1FxyzIh7HN0RRkWMmYbU,429
|
93
93
|
jarvis/jarvis_utils/utils.py,sha256=dTFIN6EV48BuC4VOyvcVcj4P0tsWysc9ennbMRhLJjk,10960
|
94
|
-
jarvis_ai_assistant-0.1.
|
95
|
-
jarvis_ai_assistant-0.1.
|
96
|
-
jarvis_ai_assistant-0.1.
|
97
|
-
jarvis_ai_assistant-0.1.
|
98
|
-
jarvis_ai_assistant-0.1.
|
99
|
-
jarvis_ai_assistant-0.1.
|
94
|
+
jarvis_ai_assistant-0.1.188.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
95
|
+
jarvis_ai_assistant-0.1.188.dist-info/METADATA,sha256=rZMrwx4kWz3yKD4jlL5fqJw8L-zMYb8ZEhv3gIlmZMc,15923
|
96
|
+
jarvis_ai_assistant-0.1.188.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
97
|
+
jarvis_ai_assistant-0.1.188.dist-info/entry_points.txt,sha256=Gy3DOP1PYLMK0GCj4rrP_9lkOyBQ39EK_lKGUSwn41E,869
|
98
|
+
jarvis_ai_assistant-0.1.188.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
99
|
+
jarvis_ai_assistant-0.1.188.dist-info/RECORD,,
|
File without changes
|
{jarvis_ai_assistant-0.1.186.dist-info → jarvis_ai_assistant-0.1.188.dist-info}/entry_points.txt
RENAMED
File without changes
|
{jarvis_ai_assistant-0.1.186.dist-info → jarvis_ai_assistant-0.1.188.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
{jarvis_ai_assistant-0.1.186.dist-info → jarvis_ai_assistant-0.1.188.dist-info}/top_level.txt
RENAMED
File without changes
|