jarvis-ai-assistant 0.1.158__py3-none-any.whl → 0.1.159__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/patch.py +72 -67
- jarvis/jarvis_code_analysis/code_review.py +34 -23
- jarvis/jarvis_git_utils/git_commiter.py +54 -14
- jarvis/jarvis_tools/registry.py +26 -6
- jarvis/jarvis_utils/methodology.py +41 -16
- jarvis/jarvis_utils/utils.py +11 -1
- {jarvis_ai_assistant-0.1.158.dist-info → jarvis_ai_assistant-0.1.159.dist-info}/METADATA +2 -2
- {jarvis_ai_assistant-0.1.158.dist-info → jarvis_ai_assistant-0.1.159.dist-info}/RECORD +13 -13
- {jarvis_ai_assistant-0.1.158.dist-info → jarvis_ai_assistant-0.1.159.dist-info}/WHEEL +1 -1
- {jarvis_ai_assistant-0.1.158.dist-info → jarvis_ai_assistant-0.1.159.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.158.dist-info → jarvis_ai_assistant-0.1.159.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.158.dist-info → jarvis_ai_assistant-0.1.159.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/patch.py
CHANGED
|
@@ -15,7 +15,7 @@ from jarvis.jarvis_utils.git_utils import get_commits_between, get_latest_commit
|
|
|
15
15
|
from jarvis.jarvis_utils.globals import add_read_file_record, has_read_file
|
|
16
16
|
from jarvis.jarvis_utils.input import get_multiline_input
|
|
17
17
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
18
|
-
from jarvis.jarvis_utils.utils import get_file_line_count, user_confirm
|
|
18
|
+
from jarvis.jarvis_utils.utils import get_file_line_count, user_confirm, chat_with_files
|
|
19
19
|
from jarvis.jarvis_utils.tag import ot, ct
|
|
20
20
|
|
|
21
21
|
|
|
@@ -95,7 +95,7 @@ def add(a, b):
|
|
|
95
95
|
- 保持代码风格一致性,遵循项目现有的编码规范
|
|
96
96
|
- 在修改前仔细分析原代码的格式风格,确保补丁与之完全兼容
|
|
97
97
|
- 绝不提供完整文件内容,除非是新建文件
|
|
98
|
-
-
|
|
98
|
+
- 每个文件的修改是独立的,不能出现"参照xxx文件的修改"这样的描述
|
|
99
99
|
- 不要出现未实现的代码,如:TODO
|
|
100
100
|
"""
|
|
101
101
|
|
|
@@ -376,12 +376,7 @@ def handle_small_code_operation(filepath: str, patch_content: str) -> bool:
|
|
|
376
376
|
with yaspin(text=f"正在修改文件 {filepath}...", color="cyan") as spinner:
|
|
377
377
|
try:
|
|
378
378
|
model = PlatformRegistry().get_normal_platform()
|
|
379
|
-
upload_success = False
|
|
380
379
|
file_content = FileOperationTool().execute({"operation":"read", "files":[{"path":filepath}]})["stdout"]
|
|
381
|
-
with spinner.hidden():
|
|
382
|
-
if get_context_token_count(file_content) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE and model.upload_files([filepath]):
|
|
383
|
-
upload_success = True
|
|
384
|
-
|
|
385
380
|
model.set_suppress_output(True)
|
|
386
381
|
|
|
387
382
|
prompt = f"""
|
|
@@ -412,9 +407,6 @@ def handle_small_code_operation(filepath: str, patch_content: str) -> bool:
|
|
|
412
407
|
{ot("MERGED_CODE")}
|
|
413
408
|
[合并后的完整代码,包括所有空行和缩进]
|
|
414
409
|
{ct("MERGED_CODE")}
|
|
415
|
-
"""
|
|
416
|
-
if not upload_success:
|
|
417
|
-
prompt += f"""
|
|
418
410
|
# 原始代码
|
|
419
411
|
{file_content}
|
|
420
412
|
"""
|
|
@@ -479,13 +471,10 @@ def handle_large_code_operation(filepath: str, patch_content: str, model: BasePl
|
|
|
479
471
|
with yaspin(text=f"正在处理文件 {filepath}...", color="cyan") as spinner:
|
|
480
472
|
try:
|
|
481
473
|
file_content = FileOperationTool().execute({"operation":"read", "files":[{"path":filepath}]})["stdout"]
|
|
482
|
-
|
|
483
|
-
#
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
upload_success = True
|
|
487
|
-
|
|
488
|
-
|
|
474
|
+
|
|
475
|
+
# 检查是否需要特殊处理大文件
|
|
476
|
+
need_special_handling = get_context_token_count(file_content) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE
|
|
477
|
+
|
|
489
478
|
model.set_suppress_output(True)
|
|
490
479
|
|
|
491
480
|
prompt = f"""
|
|
@@ -498,7 +487,8 @@ def handle_large_code_operation(filepath: str, patch_content: str, model: BasePl
|
|
|
498
487
|
```
|
|
499
488
|
{patch_content}
|
|
500
489
|
```
|
|
501
|
-
|
|
490
|
+
"""
|
|
491
|
+
suffix_prompt = """
|
|
502
492
|
## 补丁生成要求
|
|
503
493
|
1. **精确性**:严格按照补丁的意图修改代码
|
|
504
494
|
2. **格式一致性**:严格保持原始代码的格式风格
|
|
@@ -533,62 +523,77 @@ def handle_large_code_operation(filepath: str, patch_content: str, model: BasePl
|
|
|
533
523
|
<<<<<< REPLACE
|
|
534
524
|
{ct("DIFF")}
|
|
535
525
|
"""
|
|
536
|
-
if
|
|
526
|
+
if need_special_handling:
|
|
527
|
+
# 尝试上传文件
|
|
528
|
+
upload_success = False
|
|
529
|
+
with spinner.hidden():
|
|
530
|
+
if model.upload_files([filepath]):
|
|
531
|
+
upload_success = True
|
|
532
|
+
|
|
533
|
+
if upload_success:
|
|
534
|
+
response = model.chat_until_success(prompt + suffix_prompt)
|
|
535
|
+
else:
|
|
536
|
+
# 使用chat_with_files生成补丁
|
|
537
|
+
response = chat_with_files(
|
|
538
|
+
[filepath],
|
|
539
|
+
model,
|
|
540
|
+
prompt,
|
|
541
|
+
suffix_prompt
|
|
542
|
+
)
|
|
543
|
+
else:
|
|
544
|
+
# 上下文足够,直接在prompt中包含文件内容
|
|
537
545
|
prompt += f"""
|
|
538
|
-
#
|
|
546
|
+
# 原始文件内容
|
|
547
|
+
```
|
|
539
548
|
{file_content}
|
|
549
|
+
```
|
|
540
550
|
"""
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
#
|
|
562
|
-
if search_text
|
|
563
|
-
#
|
|
564
|
-
|
|
565
|
-
prompt = f"补丁 #{patch_count} 应用失败:找到多个匹配的代码段"
|
|
566
|
-
spinner.write(f"❌ 补丁 #{patch_count} 应用失败:找到多个匹配的代码段")
|
|
567
|
-
success = False
|
|
568
|
-
break
|
|
569
|
-
# 应用替换
|
|
570
|
-
modified_content = modified_content.replace(
|
|
571
|
-
search_text, replace_text)
|
|
572
|
-
spinner.write(f"✅ 补丁 #{patch_count} 应用成功")
|
|
573
|
-
else:
|
|
574
|
-
spinner.write(f"❌ 补丁 #{patch_count} 应用失败:无法找到匹配的代码段")
|
|
575
|
-
prompt = f"补丁 #{patch_count} 应用失败:无法找到匹配的代码段"
|
|
551
|
+
response = model.chat_until_success(prompt + suffix_prompt)
|
|
552
|
+
|
|
553
|
+
# 解析差异化补丁
|
|
554
|
+
diff_blocks = re.finditer(ot("DIFF")+r'\s*>{4,} SEARCH\n?(.*?)\n?={4,}\n?(.*?)\s*<{4,} REPLACE\n?'+ct("DIFF"),
|
|
555
|
+
response, re.DOTALL)
|
|
556
|
+
|
|
557
|
+
# 读取原始文件内容
|
|
558
|
+
with open(filepath, 'r', encoding='utf-8', errors="ignore") as f:
|
|
559
|
+
file_content = f.read()
|
|
560
|
+
|
|
561
|
+
# 应用所有差异化补丁
|
|
562
|
+
modified_content = file_content
|
|
563
|
+
patch_count = 0
|
|
564
|
+
success = True
|
|
565
|
+
for match in diff_blocks:
|
|
566
|
+
search_text = match.group(1).strip()
|
|
567
|
+
replace_text = match.group(2).strip()
|
|
568
|
+
patch_count += 1
|
|
569
|
+
# 检查搜索文本是否存在于文件中
|
|
570
|
+
if search_text in modified_content:
|
|
571
|
+
# 如果有多处,报错
|
|
572
|
+
if modified_content.count(search_text) > 1:
|
|
573
|
+
prompt = f"补丁 #{patch_count} 应用失败:找到多个匹配的代码段"
|
|
574
|
+
spinner.write(f"❌ 补丁 #{patch_count} 应用失败:找到多个匹配的代码段")
|
|
576
575
|
success = False
|
|
577
576
|
break
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
577
|
+
# 应用替换
|
|
578
|
+
modified_content = modified_content.replace(
|
|
579
|
+
search_text, replace_text)
|
|
580
|
+
spinner.write(f"✅ 补丁 #{patch_count} 应用成功")
|
|
581
|
+
else:
|
|
582
|
+
spinner.write(f"❌ 补丁 #{patch_count} 应用失败:无法找到匹配的代码段")
|
|
583
|
+
prompt = f"补丁 #{patch_count} 应用失败:无法找到匹配的代码段"
|
|
584
|
+
success = False
|
|
585
|
+
break
|
|
586
|
+
if not success:
|
|
587
|
+
revert_file(filepath)
|
|
588
|
+
return False
|
|
581
589
|
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
590
|
+
# 写入修改后的内容
|
|
591
|
+
with open(filepath, 'w', encoding='utf-8', errors="ignore") as f:
|
|
592
|
+
f.write(modified_content)
|
|
585
593
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
spinner.text = f"文件 {filepath} 修改失败"
|
|
590
|
-
spinner.fail("❌")
|
|
591
|
-
return False
|
|
594
|
+
spinner.text = f"文件 {filepath} 修改完成,应用了 {patch_count} 个补丁"
|
|
595
|
+
spinner.ok("✅")
|
|
596
|
+
return True
|
|
592
597
|
|
|
593
598
|
except Exception as e:
|
|
594
599
|
spinner.text = f"文件修改失败: {str(e)}"
|
|
@@ -13,7 +13,7 @@ from jarvis.jarvis_agent import Agent
|
|
|
13
13
|
from jarvis.jarvis_utils.config import INPUT_WINDOW_REVERSE_SIZE, get_max_input_token_count
|
|
14
14
|
from jarvis.jarvis_utils.embedding import get_context_token_count
|
|
15
15
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
16
|
-
from jarvis.jarvis_utils.utils import init_env
|
|
16
|
+
from jarvis.jarvis_utils.utils import init_env, chat_with_files
|
|
17
17
|
from jarvis.jarvis_utils.tag import ot, ct
|
|
18
18
|
from jarvis.jarvis_code_analysis.checklists.loader import get_language_checklist
|
|
19
19
|
|
|
@@ -587,24 +587,28 @@ class CodeReviewTool:
|
|
|
587
587
|
temp_file.flush()
|
|
588
588
|
|
|
589
589
|
try:
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
with yaspin(text="正在上传代码差异文件...", color="cyan") as spinner:
|
|
593
|
-
if get_context_token_count(diff_output) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE and agent.model and hasattr(agent.model, 'upload_files'):
|
|
594
|
-
upload_success = agent.model.upload_files([temp_file_path])
|
|
595
|
-
if upload_success:
|
|
596
|
-
spinner.ok("✅")
|
|
597
|
-
PrettyOutput.print(f"已成功上传代码差异文件", OutputType.SUCCESS)
|
|
598
|
-
upload_success = True
|
|
599
|
-
else:
|
|
600
|
-
upload_success = False
|
|
601
|
-
else:
|
|
602
|
-
upload_success = False
|
|
590
|
+
# 检查文件大小
|
|
591
|
+
is_large_file = get_context_token_count(diff_output) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE
|
|
603
592
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
593
|
+
if is_large_file:
|
|
594
|
+
# 文件较大,尝试上传
|
|
595
|
+
upload_success = False
|
|
596
|
+
with yaspin(text="正在上传代码差异文件...", color="cyan") as spinner:
|
|
597
|
+
if agent.model and hasattr(agent.model, 'upload_files'):
|
|
598
|
+
upload_success = agent.model.upload_files([temp_file_path])
|
|
599
|
+
if upload_success:
|
|
600
|
+
spinner.ok("✅")
|
|
601
|
+
PrettyOutput.print(f"已成功上传代码差异文件", OutputType.SUCCESS)
|
|
602
|
+
else:
|
|
603
|
+
spinner.fail("❌")
|
|
604
|
+
PrettyOutput.print(f"文件上传失败,将使用chat_with_files处理", OutputType.WARNING)
|
|
605
|
+
else:
|
|
606
|
+
spinner.fail("❌")
|
|
607
|
+
PrettyOutput.print(f"模型不支持文件上传,将使用chat_with_files处理", OutputType.WARNING)
|
|
608
|
+
|
|
609
|
+
if upload_success:
|
|
610
|
+
# 文件上传成功,使用上传的文件
|
|
611
|
+
complete_prompt = user_prompt + f"""
|
|
608
612
|
|
|
609
613
|
我已上传了一个包含代码差异的文件。该文件包含:
|
|
610
614
|
- 审查类型: {review_type}
|
|
@@ -612,13 +616,20 @@ class CodeReviewTool:
|
|
|
612
616
|
- 检测到的编程语言: {', '.join(detected_languages) if detected_languages else '未检测到特定语言'}
|
|
613
617
|
|
|
614
618
|
请基于上传的代码差异文件进行全面审查,并生成详细的代码审查报告。"""
|
|
619
|
+
result = agent.run(complete_prompt)
|
|
620
|
+
else:
|
|
621
|
+
# 文件上传失败,使用chat_with_files
|
|
622
|
+
PrettyOutput.print("使用chat_with_files处理大文件...", OutputType.INFO)
|
|
623
|
+
result = chat_with_files(
|
|
624
|
+
[temp_file_path],
|
|
625
|
+
agent.model,
|
|
626
|
+
user_prompt,
|
|
627
|
+
"请基于以上代码差异进行全面审查,并生成详细的代码审查报告。"
|
|
628
|
+
)
|
|
615
629
|
else:
|
|
616
|
-
#
|
|
630
|
+
# 文件较小,直接包含在prompt中
|
|
617
631
|
complete_prompt = user_prompt + "\n\n代码差异内容:\n```diff\n" + diff_output + "\n```"
|
|
618
|
-
|
|
619
|
-
# Run the agent with the prompt
|
|
620
|
-
|
|
621
|
-
result = agent.run(complete_prompt)
|
|
632
|
+
result = agent.run(complete_prompt)
|
|
622
633
|
finally:
|
|
623
634
|
# Clean up the temporary file
|
|
624
635
|
if os.path.exists(temp_file_path):
|
|
@@ -14,7 +14,7 @@ from jarvis.jarvis_utils.config import INPUT_WINDOW_REVERSE_SIZE, get_max_input_
|
|
|
14
14
|
from jarvis.jarvis_utils.embedding import get_context_token_count
|
|
15
15
|
from jarvis.jarvis_utils.git_utils import find_git_root, has_uncommitted_changes
|
|
16
16
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
17
|
-
from jarvis.jarvis_utils.utils import init_env
|
|
17
|
+
from jarvis.jarvis_utils.utils import init_env, chat_with_files
|
|
18
18
|
from jarvis.jarvis_utils.tag import ot, ct
|
|
19
19
|
|
|
20
20
|
|
|
@@ -132,9 +132,13 @@ class GitCommitTool:
|
|
|
132
132
|
|
|
133
133
|
# 获取模型并尝试上传文件
|
|
134
134
|
platform = PlatformRegistry().get_normal_platform()
|
|
135
|
-
upload_success = False
|
|
136
135
|
|
|
137
|
-
|
|
136
|
+
# 检查文件大小
|
|
137
|
+
is_large_file = get_context_token_count(diff) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE
|
|
138
|
+
|
|
139
|
+
if is_large_file:
|
|
140
|
+
# 文件较大,尝试上传
|
|
141
|
+
upload_success = False
|
|
138
142
|
spinner.text = "正在上传代码差异文件..."
|
|
139
143
|
try:
|
|
140
144
|
with spinner.hidden():
|
|
@@ -144,27 +148,63 @@ class GitCommitTool:
|
|
|
144
148
|
temp_diff_file.write(diff)
|
|
145
149
|
temp_diff_file.flush()
|
|
146
150
|
spinner.write(f"✅ 差异内容已写入临时文件")
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
151
|
+
|
|
152
|
+
if hasattr(platform, 'upload_files'):
|
|
153
|
+
upload_success = platform.upload_files([temp_diff_file_path])
|
|
154
|
+
if upload_success:
|
|
155
|
+
spinner.write("✅ 成功上传代码差异文件")
|
|
156
|
+
else:
|
|
157
|
+
spinner.write("⚠️ 上传代码差异文件失败,将使用chat_with_files处理")
|
|
158
|
+
else:
|
|
159
|
+
spinner.write("⚠️ 模型不支持文件上传,将使用chat_with_files处理")
|
|
152
160
|
except Exception as e:
|
|
153
161
|
spinner.write(f"⚠️ 上传文件时出错: {str(e)}")
|
|
154
162
|
upload_success = False
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
prompt = base_prompt + f'''
|
|
163
|
+
|
|
164
|
+
if upload_success:
|
|
165
|
+
# 使用上传的文件
|
|
166
|
+
prompt = base_prompt + f'''
|
|
160
167
|
# 变更概述
|
|
161
168
|
- 变更文件数量: {file_count} 个文件
|
|
162
169
|
- 已上传包含完整代码差异的文件
|
|
163
170
|
|
|
164
171
|
请详细分析已上传的代码差异文件,生成符合上述格式的提交信息。
|
|
165
172
|
'''
|
|
173
|
+
else:
|
|
174
|
+
# 使用chat_with_files处理大文件
|
|
175
|
+
spinner.write("使用chat_with_files处理大文件...")
|
|
176
|
+
commit_message = chat_with_files(
|
|
177
|
+
[temp_diff_file_path],
|
|
178
|
+
platform,
|
|
179
|
+
base_prompt,
|
|
180
|
+
"请基于以上代码差异生成符合格式的提交信息。"
|
|
181
|
+
)
|
|
182
|
+
commit_message = self._extract_commit_message(commit_message)
|
|
183
|
+
if commit_message:
|
|
184
|
+
spinner.write("✅ 生成提交消息")
|
|
185
|
+
# 执行提交
|
|
186
|
+
spinner.text = "正在准备提交..."
|
|
187
|
+
with tempfile.NamedTemporaryFile(mode='w', delete=True) as tmp_file:
|
|
188
|
+
tmp_file.write(commit_message)
|
|
189
|
+
tmp_file.flush()
|
|
190
|
+
spinner.text = "正在执行提交..."
|
|
191
|
+
commit_cmd = ["git", "commit", "-F", tmp_file.name]
|
|
192
|
+
subprocess.Popen(
|
|
193
|
+
commit_cmd,
|
|
194
|
+
stdout=subprocess.DEVNULL,
|
|
195
|
+
stderr=subprocess.DEVNULL
|
|
196
|
+
).wait()
|
|
197
|
+
spinner.write("✅ 提交")
|
|
198
|
+
return {
|
|
199
|
+
"success": True,
|
|
200
|
+
"stdout": yaml.safe_dump({
|
|
201
|
+
"commit_hash": self._get_last_commit_hash(),
|
|
202
|
+
"commit_message": commit_message
|
|
203
|
+
}),
|
|
204
|
+
"stderr": ""
|
|
205
|
+
}
|
|
166
206
|
else:
|
|
167
|
-
#
|
|
207
|
+
# 文件较小,直接在提示中包含差异内容
|
|
168
208
|
prompt = base_prompt + f'''
|
|
169
209
|
# 分析材料
|
|
170
210
|
{diff}
|
jarvis/jarvis_tools/registry.py
CHANGED
|
@@ -630,14 +630,34 @@ class ToolRegistry(OutputHandler):
|
|
|
630
630
|
if platform:
|
|
631
631
|
platform.set_suppress_output(False)
|
|
632
632
|
try:
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
633
|
+
# 尝试上传文件
|
|
634
|
+
if platform.upload_files([output_file]):
|
|
635
|
+
prompt = f"""该文件为工具执行结果,请阅读文件内容,并根据文件提取出以下信息:{want}
|
|
636
|
+
|
|
637
|
+
注意:
|
|
638
|
+
1. 请仔细阅读文件内容,确保提取的信息准确完整
|
|
639
|
+
2. 如果文件内容包含错误信息,请特别关注并提取
|
|
640
|
+
3. 提取的信息应该直接回答用户的问题,不要包含无关内容"""
|
|
641
|
+
return f"""工具调用原始输出过长,以下是根据输出提出的信息:
|
|
639
642
|
|
|
640
643
|
{platform.chat_until_success(prompt)}"""
|
|
644
|
+
else:
|
|
645
|
+
# 上传失败,使用chat_with_files
|
|
646
|
+
PrettyOutput.print("⚠️ 上传文件失败,将使用chat_with_files处理", OutputType.WARNING)
|
|
647
|
+
from jarvis.jarvis_utils.utils import chat_with_files
|
|
648
|
+
prompt = f"""请阅读以下文件内容,并根据文件提取出以下信息:{want}
|
|
649
|
+
|
|
650
|
+
注意:
|
|
651
|
+
1. 请仔细阅读文件内容,确保提取的信息准确完整
|
|
652
|
+
2. 如果文件内容包含错误信息,请特别关注并提取
|
|
653
|
+
3. 提取的信息应该直接回答用户的问题,不要包含无关内容"""
|
|
654
|
+
return f"""工具调用原始输出过长,以下是根据输出提出的信息:
|
|
655
|
+
|
|
656
|
+
{chat_with_files([output_file], platform, prompt, "")}"""
|
|
657
|
+
except Exception as e:
|
|
658
|
+
PrettyOutput.print(f"处理大文件时出错: {str(e)}", OutputType.ERROR)
|
|
659
|
+
return self._truncate_output(output)
|
|
660
|
+
return self._truncate_output(output)
|
|
641
661
|
|
|
642
662
|
return output
|
|
643
663
|
|
|
@@ -122,7 +122,7 @@ def load_methodology(user_input: str) -> str:
|
|
|
122
122
|
# 获取当前平台
|
|
123
123
|
platform = PlatformRegistry().get_normal_platform()
|
|
124
124
|
|
|
125
|
-
|
|
125
|
+
# 检查是否需要特殊处理大文件
|
|
126
126
|
if get_context_token_count(user_input) > get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE:
|
|
127
127
|
# 创建临时文件
|
|
128
128
|
with yaspin(text="创建方法论临时文件...", color="yellow") as spinner:
|
|
@@ -133,22 +133,48 @@ def load_methodology(user_input: str) -> str:
|
|
|
133
133
|
return ""
|
|
134
134
|
spinner.text = f"创建方法论临时文件完成: {temp_file_path}"
|
|
135
135
|
spinner.ok("✅")
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
136
|
+
|
|
137
|
+
# 尝试上传文件
|
|
138
|
+
upload_success = False
|
|
139
|
+
try:
|
|
140
|
+
if platform.upload_files([temp_file_path]):
|
|
141
|
+
upload_success = True
|
|
142
|
+
spinner.write("✅ 成功上传方法论文件")
|
|
143
|
+
else:
|
|
144
|
+
spinner.write("⚠️ 上传方法论文件失败,将使用chat_with_files处理")
|
|
145
|
+
except Exception as e:
|
|
146
|
+
spinner.write(f"⚠️ 上传文件时出错: {str(e)}")
|
|
147
|
+
upload_success = False
|
|
148
|
+
|
|
149
|
+
# 构建提示信息
|
|
150
|
+
prompt = f"""请根据以下方法论内容,总结出与以下用户需求相关的方法论: {user_input}
|
|
151
|
+
|
|
152
|
+
请按以下格式回复:
|
|
153
|
+
### 与该任务/需求相关的方法论
|
|
154
|
+
1. [方法论名字]
|
|
155
|
+
2. [方法论名字]
|
|
156
|
+
### 根据以上方法论,总结出方法论内容
|
|
157
|
+
[总结的方法论内容]
|
|
158
|
+
|
|
159
|
+
如果没有匹配的方法论,请输出:没有历史方法论可参考
|
|
160
|
+
除以上要求外,不要输出任何内容"""
|
|
161
|
+
|
|
162
|
+
if upload_success:
|
|
163
|
+
# 使用上传的文件
|
|
164
|
+
return platform.chat_until_success(prompt)
|
|
165
|
+
else:
|
|
166
|
+
# 使用chat_with_files处理大文件
|
|
167
|
+
from jarvis.jarvis_utils.utils import chat_with_files
|
|
168
|
+
return chat_with_files([temp_file_path], platform, prompt, "")
|
|
169
|
+
else:
|
|
170
|
+
# 上下文足够,直接在prompt中包含方法论内容
|
|
171
|
+
prompt = f"""以下是所有可用的方法论内容:
|
|
145
172
|
|
|
146
173
|
"""
|
|
147
|
-
if not upload_result:
|
|
148
174
|
for problem_type, content in methodologies.items():
|
|
149
175
|
prompt += f"## {problem_type}\n\n{content}\n\n---\n\n"
|
|
150
|
-
|
|
151
|
-
|
|
176
|
+
|
|
177
|
+
prompt += f"""
|
|
152
178
|
请根据以上方法论内容,总结出与以下用户需求相关的方法论: {user_input}
|
|
153
179
|
|
|
154
180
|
请按以下格式回复:
|
|
@@ -159,9 +185,8 @@ def load_methodology(user_input: str) -> str:
|
|
|
159
185
|
[总结的方法论内容]
|
|
160
186
|
|
|
161
187
|
如果没有匹配的方法论,请输出:没有历史方法论可参考
|
|
162
|
-
除以上要求外,不要输出任何内容
|
|
163
|
-
|
|
164
|
-
return platform.chat_until_success(prompt)
|
|
188
|
+
除以上要求外,不要输出任何内容"""
|
|
189
|
+
return platform.chat_until_success(prompt)
|
|
165
190
|
|
|
166
191
|
except Exception as e:
|
|
167
192
|
PrettyOutput.print(f"加载方法论失败: {str(e)}", OutputType.ERROR)
|
jarvis/jarvis_utils/utils.py
CHANGED
|
@@ -4,7 +4,7 @@ import hashlib
|
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import List, Any, Callable
|
|
6
6
|
from jarvis.jarvis_utils.config import get_max_input_token_count, get_data_dir
|
|
7
|
-
from jarvis.jarvis_utils.embedding import get_context_token_count
|
|
7
|
+
from jarvis.jarvis_utils.embedding import get_context_token_count, split_text_into_chunks
|
|
8
8
|
from jarvis.jarvis_utils.input import get_single_line_input
|
|
9
9
|
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
10
10
|
def init_env() -> None:
|
|
@@ -130,3 +130,13 @@ def is_long_context(files: List[str]) -> bool:
|
|
|
130
130
|
return total_tokens > threshold
|
|
131
131
|
|
|
132
132
|
|
|
133
|
+
def chat_with_files(files: List[str], platform: Any, prompt_prefix: str, prompt_suffix: str) -> str:
|
|
134
|
+
from jarvis.jarvis_platform.base import BasePlatform
|
|
135
|
+
from jarvis.jarvis_tools.file_operation import FileOperationTool
|
|
136
|
+
platform_: BasePlatform = platform
|
|
137
|
+
file_content = FileOperationTool().execute({"operation":"read", "files":files})["stdout"]
|
|
138
|
+
file_content_chuck = split_text_into_chunks(file_content, get_max_input_token_count()-2048)
|
|
139
|
+
platform_.chat_until_success(prompt_prefix)
|
|
140
|
+
for file_content_chunk in file_content_chuck:
|
|
141
|
+
platform_.chat_until_success(file_content_chunk)
|
|
142
|
+
return platform_.chat_until_success(prompt_suffix)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jarvis-ai-assistant
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.159
|
|
4
4
|
Summary: Jarvis: An AI assistant that uses tools to interact with the system
|
|
5
5
|
Home-page: https://github.com/skyfireitdiy/Jarvis
|
|
6
6
|
Author: skyfire
|
|
@@ -194,7 +194,7 @@ jarvis-methodology --help
|
|
|
194
194
|
### 环境变量配置
|
|
195
195
|
| 变量名称 | 默认值 | 说明 |
|
|
196
196
|
|----------|--------|------|
|
|
197
|
-
| `JARVIS_MAX_TOKEN_COUNT` | 102400000 |
|
|
197
|
+
| `JARVIS_MAX_TOKEN_COUNT` | 102400000 | 上下文最大token数量 |
|
|
198
198
|
| `JARVIS_MAX_INPUT_TOKEN_COUNT` | 32000 | 输入的最大token数量 |
|
|
199
199
|
| `JARVIS_AUTO_COMPLETE` | false | 是否启用自动完成功能(任务判定完成的时候会自动终止) |
|
|
200
200
|
| `JARVIS_SHELL_NAME` | bash | 系统shell名称 |
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
jarvis/__init__.py,sha256=
|
|
1
|
+
jarvis/__init__.py,sha256=_IZ4qsot_luvb5GqI5sZmjlOdVcITvyPV8qcjgeUK4Y,50
|
|
2
2
|
jarvis/jarvis_agent/__init__.py,sha256=tii6khwfG971MJiMfKSLwlKTjB3iEv8ITE3JqYSkfQA,24824
|
|
3
3
|
jarvis/jarvis_agent/builtin_input_handler.py,sha256=3rRA-7v_VUSFG1s7tTKhriq9vv0nsa3t69ReV0xH5gs,1505
|
|
4
4
|
jarvis/jarvis_agent/file_input_handler.py,sha256=auBbBfS4Ux5ksczeRe9LtsmMm4hKrPxinW5leE9Rtyc,3575
|
|
5
5
|
jarvis/jarvis_agent/jarvis.py,sha256=6Bp_Y-E3RN6bDmDs5lN3uALL_Dhq-p_aIuVNELG1vtw,5898
|
|
6
6
|
jarvis/jarvis_agent/main.py,sha256=Jlw_Tofh2C-sMVnkeOZBrwWJOWNH3IhsKDUn-WBlgU8,2602
|
|
7
7
|
jarvis/jarvis_agent/output_handler.py,sha256=4limQ-Kf-YYvQjT5SMjJIyyvD1DVG8tINv1A_qbv4ho,405
|
|
8
|
-
jarvis/jarvis_agent/patch.py,sha256=
|
|
8
|
+
jarvis/jarvis_agent/patch.py,sha256=LjOlnd6AoG9RyzphmCdv9J514-aOX_bXG67lXXQxEvo,23673
|
|
9
9
|
jarvis/jarvis_agent/shell_input_handler.py,sha256=9IoGQCe6FF4HA2V5S11q63AtnWDZFpNeRd3hcqCAlBw,1237
|
|
10
10
|
jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
11
|
jarvis/jarvis_code_agent/code_agent.py,sha256=vi_g-LWdD5nn3RQsC1X8G2iNK8SrBADwFLUkflqtvKE,13723
|
|
12
|
-
jarvis/jarvis_code_analysis/code_review.py,sha256=
|
|
12
|
+
jarvis/jarvis_code_analysis/code_review.py,sha256=wCnj2qr4QhIvcItn8aOCqDqjrEjRnw7mtYHhlkK29xE,30599
|
|
13
13
|
jarvis/jarvis_code_analysis/checklists/__init__.py,sha256=PCjlyxLa939613cAzS7pfEPgP57setO-1RvcdzzPivw,54
|
|
14
14
|
jarvis/jarvis_code_analysis/checklists/c_cpp.py,sha256=8lfWmhImAxeTBdHPOgVXDjMllaq280Qki1ZOOSDBnvk,1293
|
|
15
15
|
jarvis/jarvis_code_analysis/checklists/csharp.py,sha256=fg35Iima2nIsirEmAjianfAybVjwRYml9BtbSQFff7w,2396
|
|
@@ -35,7 +35,7 @@ jarvis/jarvis_git_details/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
35
35
|
jarvis/jarvis_git_details/main.py,sha256=YowncVxYyJ3y2EvGrZhAJeR4yizXp6aB3dqvoYTepFY,6117
|
|
36
36
|
jarvis/jarvis_git_squash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
37
|
jarvis/jarvis_git_squash/main.py,sha256=xBNkAl7_8_pQC-C6RcUImA1mEU4KTqhjtA57rG_mMJ8,2179
|
|
38
|
-
jarvis/jarvis_git_utils/git_commiter.py,sha256=
|
|
38
|
+
jarvis/jarvis_git_utils/git_commiter.py,sha256=hP4rQqqKtgu9kw46oK9V8rOwG2IqxAXgNuv0YHX-Qd0,13712
|
|
39
39
|
jarvis/jarvis_lsp/base.py,sha256=f-76xgNijfQ4G3Q0t8IfOGtCu-q2TSQ7a_in6XwDb_8,2030
|
|
40
40
|
jarvis/jarvis_lsp/cpp.py,sha256=ekci2M9_UtkCSEe9__72h26Gat93r9_knL2VmFr8X5M,3141
|
|
41
41
|
jarvis/jarvis_lsp/go.py,sha256=sSypuQSP5X2YtrVMC8XCc5nXkgfG93SO7sC89lHzoR8,3458
|
|
@@ -74,7 +74,7 @@ jarvis/jarvis_tools/lsp_get_diagnostics.py,sha256=IYqv8jQwSK71sZpDBRolSDnYii8t0M
|
|
|
74
74
|
jarvis/jarvis_tools/methodology.py,sha256=gnlJojY4Dg5v9AAB5xcpKqpPIHs0tOYVtzTHkwOrWk0,5214
|
|
75
75
|
jarvis/jarvis_tools/read_code.py,sha256=_X6D3AIgRD9YplSDnFhXOm8wQAZMA3pkkXy31SG33l0,6041
|
|
76
76
|
jarvis/jarvis_tools/read_webpage.py,sha256=1AXXEX69fPJsPL7PBZDM1G4Z-MM13pUt34JXitsAFM4,2022
|
|
77
|
-
jarvis/jarvis_tools/registry.py,sha256=
|
|
77
|
+
jarvis/jarvis_tools/registry.py,sha256=ZI5MHhtHm6UvdarvIVu0Kg8BuqV4MIVvVGwOa8yWh74,27531
|
|
78
78
|
jarvis/jarvis_tools/search_web.py,sha256=hMrcSnKcjH6YcV8WY4tangEid7y1L-QbyeXDlBofoy8,756
|
|
79
79
|
jarvis/jarvis_tools/virtual_tty.py,sha256=Rpn9VXUG17LQsY87F_O6UCjN_opXB05mpwozxYf-xVI,16372
|
|
80
80
|
jarvis/jarvis_utils/__init__.py,sha256=KMg-KY5rZIhGTeOD5e2Xo5CU7DX1DUz4ULWAaTQ-ZNw,825
|
|
@@ -85,13 +85,13 @@ jarvis/jarvis_utils/file_processors.py,sha256=oNtVlz2JHcQ60NS6sgI-VsvYXOnsQgFUEV
|
|
|
85
85
|
jarvis/jarvis_utils/git_utils.py,sha256=j_Jw6h7JD91XhMf0WD3MAH4URkLUBrrYCLnuLm1GeN4,5630
|
|
86
86
|
jarvis/jarvis_utils/globals.py,sha256=Ed2d6diWXCgI74HVV_tI4qW7yXxLpNvQKN2yG0IH9hc,3388
|
|
87
87
|
jarvis/jarvis_utils/input.py,sha256=zvL-JQSJvkmsZB7ApJsaVpk46BkpmJA3I_BnWSl_D-4,7299
|
|
88
|
-
jarvis/jarvis_utils/methodology.py,sha256=
|
|
88
|
+
jarvis/jarvis_utils/methodology.py,sha256=OKD3OwScJgpTilrAt38Iu5Xlp3_i6joPZB82TE8PAZw,7592
|
|
89
89
|
jarvis/jarvis_utils/output.py,sha256=BmWdB1bmizv0xfU4Z___9p_xQodorriIcEgADVq9fk0,8416
|
|
90
90
|
jarvis/jarvis_utils/tag.py,sha256=YtXBYuZWy8j8YbeQX2qRrHRQl6Gp2Vt7W4p-2yjo0a4,405
|
|
91
|
-
jarvis/jarvis_utils/utils.py,sha256=
|
|
92
|
-
jarvis_ai_assistant-0.1.
|
|
93
|
-
jarvis_ai_assistant-0.1.
|
|
94
|
-
jarvis_ai_assistant-0.1.
|
|
95
|
-
jarvis_ai_assistant-0.1.
|
|
96
|
-
jarvis_ai_assistant-0.1.
|
|
97
|
-
jarvis_ai_assistant-0.1.
|
|
91
|
+
jarvis/jarvis_utils/utils.py,sha256=Qds24SeHJZShb1w4CBp3uKT3zUiltAUFyvh_KfxvBkM,4936
|
|
92
|
+
jarvis_ai_assistant-0.1.159.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
|
93
|
+
jarvis_ai_assistant-0.1.159.dist-info/METADATA,sha256=gID-zAYn10pXQXEjVrrgbu8m188dW2HV7QhOMlcyyDU,12660
|
|
94
|
+
jarvis_ai_assistant-0.1.159.dist-info/WHEEL,sha256=0CuiUZ_p9E4cD6NyLD6UG80LBXYyiSYZOKDm5lp32xk,91
|
|
95
|
+
jarvis_ai_assistant-0.1.159.dist-info/entry_points.txt,sha256=cKz_9SEpOvElTubKPMZMAdskD4GHz-NyKWRNssIVAWE,973
|
|
96
|
+
jarvis_ai_assistant-0.1.159.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
|
97
|
+
jarvis_ai_assistant-0.1.159.dist-info/RECORD,,
|
{jarvis_ai_assistant-0.1.158.dist-info → jarvis_ai_assistant-0.1.159.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.158.dist-info → jarvis_ai_assistant-0.1.159.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.158.dist-info → jarvis_ai_assistant-0.1.159.dist-info}/top_level.txt
RENAMED
|
File without changes
|