jarvis-ai-assistant 0.1.168__py3-none-any.whl → 0.1.171__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of jarvis-ai-assistant might be problematic. Click here for more details.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +246 -85
- jarvis/jarvis_agent/jarvis.py +2 -0
- jarvis/jarvis_code_agent/code_agent.py +3 -3
- jarvis/jarvis_code_analysis/code_review.py +13 -12
- jarvis/jarvis_git_utils/git_commiter.py +6 -5
- jarvis/jarvis_platform/base.py +33 -20
- jarvis/jarvis_tools/edit_file.py +7 -1
- jarvis/jarvis_tools/generate_new_tool.py +30 -81
- jarvis/jarvis_tools/registry.py +2 -6
- jarvis/jarvis_utils/config.py +10 -1
- jarvis/jarvis_utils/methodology.py +3 -19
- jarvis/jarvis_utils/utils.py +4 -35
- {jarvis_ai_assistant-0.1.168.dist-info → jarvis_ai_assistant-0.1.171.dist-info}/METADATA +2 -1
- {jarvis_ai_assistant-0.1.168.dist-info → jarvis_ai_assistant-0.1.171.dist-info}/RECORD +19 -19
- {jarvis_ai_assistant-0.1.168.dist-info → jarvis_ai_assistant-0.1.171.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.168.dist-info → jarvis_ai_assistant-0.1.171.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.168.dist-info → jarvis_ai_assistant-0.1.171.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.168.dist-info → jarvis_ai_assistant-0.1.171.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
|
@@ -421,56 +421,27 @@ class Agent:
|
|
|
421
421
|
|
|
422
422
|
with yaspin(text="正在总结对话历史...", color="cyan") as spinner:
|
|
423
423
|
|
|
424
|
-
summary_prompt = """
|
|
425
|
-
<
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
4. 如果用户明确指出了某个解决步骤的优化方向,这应该被纳入方法论
|
|
438
|
-
5. 如果用户在解决过程中发现了更高效的方法,这应被记录并优先使用
|
|
439
|
-
</evaluation_criteria>
|
|
440
|
-
|
|
441
|
-
<format_requirements>
|
|
442
|
-
方法论格式要求:
|
|
443
|
-
1. 问题重述: 简明扼要的问题归纳,不含特定细节
|
|
444
|
-
2. 最优解决方案: 经过用户验证的、最终有效的解决方案(将每个步骤要使用的工具也列举出来)
|
|
445
|
-
3. 注意事项: 执行中可能遇到的常见问题和注意点,尤其是用户指出的问题
|
|
446
|
-
4. 可选步骤: 对于有多种解决路径的问题,标注出可选步骤和适用场景
|
|
447
|
-
</format_requirements>
|
|
448
|
-
|
|
449
|
-
<quality_control>
|
|
450
|
-
方法论质量控制:
|
|
451
|
-
1. 只记录有实际意义的流程,不记录执行过程中的错误或无效尝试
|
|
452
|
-
2. 保留最终有效的解决步骤和用户认可的解决方案
|
|
453
|
-
3. 不要包含特定代码片段、文件路径或其他特定于单一任务的细节
|
|
454
|
-
4. 确保方法论遵循用户认可的执行路径,尤其是用户指出的改进点
|
|
455
|
-
</quality_control>
|
|
456
|
-
|
|
457
|
-
<output_requirements>
|
|
458
|
-
只输出方法论工具调用指令,或不生成方法论的解释。不要输出其他内容。
|
|
459
|
-
</output_requirements>
|
|
424
|
+
summary_prompt = """
|
|
425
|
+
<summary_request>
|
|
426
|
+
<objective>
|
|
427
|
+
请对当前对话历史进行简明扼要的总结,提取关键信息和重要决策点。这个总结将作为上下文继续任务,因此需要保留对后续对话至关重要的内容。
|
|
428
|
+
</objective>
|
|
429
|
+
|
|
430
|
+
<guidelines>
|
|
431
|
+
1. 提取关键信息:任务目标、已确定的事实、重要决策、达成的共识
|
|
432
|
+
2. 保留技术细节:命令、代码片段、文件路径、配置设置等技术细节
|
|
433
|
+
3. 记录任务进展:已完成的步骤、当前所处阶段、待解决的问题
|
|
434
|
+
4. 包含用户偏好:用户表达的明确偏好、限制条件或特殊要求
|
|
435
|
+
5. 省略冗余内容:问候语、重复信息、不相关的讨论
|
|
436
|
+
</guidelines>
|
|
460
437
|
|
|
461
|
-
<
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
problem_type: 方法论类型,不要过于细节,也不要过于泛化
|
|
469
|
-
content: |
|
|
470
|
-
方法论内容
|
|
471
|
-
{ct("TOOL_CALL")}
|
|
472
|
-
</template>
|
|
473
|
-
</methodology_analysis>
|
|
438
|
+
<format>
|
|
439
|
+
- 使用简洁、客观的语言
|
|
440
|
+
- 按时间顺序或主题组织信息
|
|
441
|
+
- 使用要点列表增强可读性
|
|
442
|
+
- 总结应控制在500词以内
|
|
443
|
+
</format>
|
|
444
|
+
</summary_request>
|
|
474
445
|
"""
|
|
475
446
|
|
|
476
447
|
try:
|
|
@@ -559,58 +530,162 @@ arguments:
|
|
|
559
530
|
2. 对于子Agent: 可能会生成总结(如果启用)
|
|
560
531
|
3. 使用spinner显示生成状态
|
|
561
532
|
"""
|
|
562
|
-
"""
|
|
563
|
-
|
|
564
|
-
Returns:
|
|
565
|
-
str: Task summary or completion status
|
|
566
|
-
|
|
567
|
-
Note:
|
|
568
|
-
- For main agent: May generate methodology if enabled
|
|
569
|
-
- For sub-agent: May generate summary if enabled
|
|
570
|
-
"""
|
|
571
|
-
with yaspin(text="正在生成方法论...", color="cyan") as spinner:
|
|
533
|
+
with yaspin(text="正在分析任务...", color="cyan") as spinner:
|
|
572
534
|
try:
|
|
573
|
-
|
|
574
535
|
# 让模型判断是否需要生成方法论
|
|
575
|
-
analysis_prompt = f"""<
|
|
536
|
+
analysis_prompt = f"""<task_analysis>
|
|
576
537
|
<request>
|
|
577
|
-
|
|
538
|
+
当前任务已结束,请分析该任务的解决方案:
|
|
578
539
|
|
|
579
|
-
|
|
580
|
-
|
|
540
|
+
1. 首先检查现有工具或方法论是否已经可以完成该任务,如果可以,直接说明即可,无需生成新内容
|
|
541
|
+
2. 如果现有工具/方法论不足,评估当前任务是否可以通过编写新工具来自动化解决
|
|
542
|
+
3. 如果可以通过工具解决,请设计并提供工具代码
|
|
543
|
+
4. 如果无法通过编写通用工具完成,评估是否可以总结为通用方法论
|
|
544
|
+
5. 如果以上都不可行,给出详细理由
|
|
545
|
+
|
|
546
|
+
请根据分析结果采取相应行动:说明现有工具/方法论、创建新工具、生成新方法论或说明原因。
|
|
581
547
|
</request>
|
|
582
548
|
|
|
583
549
|
<evaluation_criteria>
|
|
550
|
+
现有资源评估:
|
|
551
|
+
1. 现有工具 - 检查系统中是否已有可以完成该任务的工具
|
|
552
|
+
2. 现有方法论 - 检查是否已有适用于该任务的方法论
|
|
553
|
+
3. 组合使用 - 评估现有工具和方法论组合使用是否可以解决问题
|
|
554
|
+
|
|
555
|
+
工具评估标准:
|
|
556
|
+
1. 通用性 - 该工具是否可以解决一类问题,而不仅仅是当前特定问题
|
|
557
|
+
2. 自动化 - 该工具是否可以减少人工干预,提高效率
|
|
558
|
+
3. 可靠性 - 该工具是否可以在不同场景下稳定工作
|
|
559
|
+
4. 简单性 - 该工具是否易于使用,参数设计是否合理
|
|
560
|
+
|
|
584
561
|
方法论评估标准:
|
|
585
562
|
1. 方法论应聚焦于通用且可重复的解决方案流程
|
|
586
563
|
2. 方法论应该具备足够的通用性,可应用于同类问题
|
|
587
564
|
3. 特别注意用户在执行过程中提供的修正、反馈和改进建议
|
|
588
565
|
4. 如果用户明确指出了某个解决步骤的优化方向,这应该被纳入方法论
|
|
589
|
-
5. 如果用户在解决过程中发现了更高效的方法,这应被记录并优先使用
|
|
590
566
|
</evaluation_criteria>
|
|
591
567
|
|
|
592
|
-
<
|
|
568
|
+
<tool_requirements>
|
|
569
|
+
工具代码要求:
|
|
570
|
+
1. 工具类名应与工具名称保持一致
|
|
571
|
+
2. 必须包含name、description、parameters属性
|
|
572
|
+
3. 必须实现execute方法处理输入参数
|
|
573
|
+
4. 可选实现check方法验证环境
|
|
574
|
+
5. 工具描述应详细说明用途、适用场景和使用示例
|
|
575
|
+
6. 参数定义应遵循JSON Schema格式
|
|
576
|
+
7. 不要包含特定任务的细节,保持通用性
|
|
577
|
+
|
|
578
|
+
工具设计关键点:
|
|
579
|
+
1. **使用PrettyOutput打印执行过程**:强烈建议在工具中使用PrettyOutput显示执行过程,
|
|
580
|
+
这样用户可以了解工具在做什么,提升用户体验。示例:
|
|
581
|
+
```python
|
|
582
|
+
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
583
|
+
|
|
584
|
+
# 执行中打印信息
|
|
585
|
+
PrettyOutput.print("正在处理数据...", OutputType.INFO)
|
|
586
|
+
# 成功信息
|
|
587
|
+
PrettyOutput.print("操作成功完成", OutputType.SUCCESS)
|
|
588
|
+
# 警告信息
|
|
589
|
+
PrettyOutput.print("发现潜在问题", OutputType.WARNING)
|
|
590
|
+
# 错误信息
|
|
591
|
+
PrettyOutput.print("操作失败", OutputType.ERROR)
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
2. **结构化返回结果**:工具应该始终返回结构化的结果字典,包含以下字段:
|
|
595
|
+
- success: 布尔值,表示操作是否成功
|
|
596
|
+
- stdout: 字符串,包含工具的主要输出内容
|
|
597
|
+
- stderr: 字符串,包含错误信息(如果有)
|
|
598
|
+
|
|
599
|
+
3. **异常处理**:工具应该妥善处理可能发生的异常,并在失败时清理已创建的资源
|
|
600
|
+
```python
|
|
601
|
+
try:
|
|
602
|
+
# 执行逻辑
|
|
603
|
+
return {{
|
|
604
|
+
"success": True,
|
|
605
|
+
"stdout": "成功结果",
|
|
606
|
+
"stderr": ""
|
|
607
|
+
}}
|
|
608
|
+
except Exception as e:
|
|
609
|
+
PrettyOutput.print(f"操作失败: {{str(e)}}", OutputType.ERROR)
|
|
610
|
+
# 清理资源(如果有创建)
|
|
611
|
+
return {{
|
|
612
|
+
"success": False,
|
|
613
|
+
"stdout": "",
|
|
614
|
+
"stderr": f"操作失败: {{str(e)}}"
|
|
615
|
+
}}
|
|
616
|
+
```
|
|
617
|
+
</tool_requirements>
|
|
618
|
+
|
|
619
|
+
<methodology_requirements>
|
|
593
620
|
方法论格式要求:
|
|
594
621
|
1. 问题重述: 简明扼要的问题归纳,不含特定细节
|
|
595
622
|
2. 最优解决方案: 经过用户验证的、最终有效的解决方案(将每个步骤要使用的工具也列举出来)
|
|
596
623
|
3. 注意事项: 执行中可能遇到的常见问题和注意点,尤其是用户指出的问题
|
|
597
624
|
4. 可选步骤: 对于有多种解决路径的问题,标注出可选步骤和适用场景
|
|
598
|
-
</
|
|
599
|
-
|
|
600
|
-
<quality_control>
|
|
601
|
-
方法论质量控制:
|
|
602
|
-
1. 只记录有实际意义的流程,不记录执行过程中的错误或无效尝试
|
|
603
|
-
2. 保留最终有效的解决步骤和用户认可的解决方案
|
|
604
|
-
3. 不要包含特定代码片段、文件路径或其他特定于单一任务的细节
|
|
605
|
-
4. 确保方法论遵循用户认可的执行路径,尤其是用户指出的改进点
|
|
606
|
-
</quality_control>
|
|
625
|
+
</methodology_requirements>
|
|
607
626
|
|
|
608
627
|
<output_requirements>
|
|
609
|
-
|
|
610
|
-
|
|
628
|
+
根据分析结果,输出以下三种情况之一:
|
|
629
|
+
|
|
630
|
+
1. 如果现有工具/方法论可以解决,直接输出说明:
|
|
631
|
+
已有工具/方法论可以解决该问题,无需创建新内容。
|
|
632
|
+
可用的工具/方法论:[列出工具名称或方法论名称]
|
|
633
|
+
使用方法:[简要说明如何使用]
|
|
634
|
+
|
|
635
|
+
2. 工具创建(如果需要创建新工具):
|
|
636
|
+
{ot("TOOL_CALL")}
|
|
637
|
+
want: 创建新工具来解决XXX问题
|
|
638
|
+
name: generate_new_tool
|
|
639
|
+
arguments:
|
|
640
|
+
tool_name: 工具名称
|
|
641
|
+
tool_code: |
|
|
642
|
+
# -*- coding: utf-8 -*-
|
|
643
|
+
from typing import Dict, Any
|
|
644
|
+
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
645
|
+
|
|
646
|
+
class 工具名称:
|
|
647
|
+
name = "工具名称"
|
|
648
|
+
description = "Tool for text transformation"
|
|
649
|
+
Tool description
|
|
650
|
+
适用场景:1. 格式化文本; 2. 处理标题; 3. 标准化输出
|
|
651
|
+
\"\"\"
|
|
652
|
+
|
|
653
|
+
parameters = {{
|
|
654
|
+
"type": "object",
|
|
655
|
+
"properties": {{
|
|
656
|
+
# 参数定义
|
|
657
|
+
}},
|
|
658
|
+
"required": []
|
|
659
|
+
}}
|
|
660
|
+
|
|
661
|
+
@staticmethod
|
|
662
|
+
def check() -> bool:
|
|
663
|
+
return True
|
|
664
|
+
|
|
665
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
666
|
+
try:
|
|
667
|
+
# 使用PrettyOutput显示执行过程
|
|
668
|
+
PrettyOutput.print("开始执行操作...", OutputType.INFO)
|
|
669
|
+
|
|
670
|
+
# 实现逻辑
|
|
671
|
+
# ...
|
|
672
|
+
|
|
673
|
+
PrettyOutput.print("操作已完成", OutputType.SUCCESS)
|
|
674
|
+
return {{
|
|
675
|
+
"success": True,
|
|
676
|
+
"stdout": "结果输出",
|
|
677
|
+
"stderr": ""
|
|
678
|
+
}}
|
|
679
|
+
except Exception as e:
|
|
680
|
+
PrettyOutput.print(f"操作失败: {{str(e)}}", OutputType.ERROR)
|
|
681
|
+
return {{
|
|
682
|
+
"success": False,
|
|
683
|
+
"stdout": "",
|
|
684
|
+
"stderr": f"操作失败: {{str(e)}}"
|
|
685
|
+
}}
|
|
686
|
+
{ct("TOOL_CALL")}
|
|
611
687
|
|
|
612
|
-
|
|
613
|
-
方法论格式:
|
|
688
|
+
3. 方法论创建(如果需要创建新方法论):
|
|
614
689
|
{ot("TOOL_CALL")}
|
|
615
690
|
want: 添加/更新xxxx的方法论
|
|
616
691
|
name: methodology
|
|
@@ -620,19 +695,105 @@ arguments:
|
|
|
620
695
|
content: |
|
|
621
696
|
方法论内容
|
|
622
697
|
{ct("TOOL_CALL")}
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
698
|
+
|
|
699
|
+
如果以上三种情况都不适用,则直接输出原因分析,不要使用工具调用格式。
|
|
700
|
+
</output_requirements>
|
|
701
|
+
|
|
702
|
+
<tool_example>
|
|
703
|
+
以下是一个完整的工具示例,供参考:
|
|
704
|
+
|
|
705
|
+
```python
|
|
706
|
+
# -*- coding: utf-8 -*-
|
|
707
|
+
from typing import Dict, Any
|
|
708
|
+
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
709
|
+
|
|
710
|
+
class text_transformer:
|
|
711
|
+
name = "text_transformer"
|
|
712
|
+
description = "Tool for text transformation"
|
|
713
|
+
Tool description for text transformation
|
|
714
|
+
适用场景:1. 格式化文本; 2. 处理标题; 3. 标准化输出
|
|
715
|
+
\"\"\"
|
|
716
|
+
|
|
717
|
+
parameters = {{
|
|
718
|
+
"type": "object",
|
|
719
|
+
"properties": {{
|
|
720
|
+
"text": {{
|
|
721
|
+
"type": "string",
|
|
722
|
+
"description": "需要转换格式的文本"
|
|
723
|
+
}},
|
|
724
|
+
"transform_type": {{
|
|
725
|
+
"type": "string",
|
|
726
|
+
"description": "转换类型,可选值为 upper(大写)、lower(小写)或 title(首字母大写)",
|
|
727
|
+
"enum": ["upper", "lower", "title"]
|
|
728
|
+
}}
|
|
729
|
+
}},
|
|
730
|
+
"required": ["text", "transform_type"]
|
|
731
|
+
}}
|
|
732
|
+
|
|
733
|
+
@staticmethod
|
|
734
|
+
def check() -> bool:
|
|
735
|
+
return True
|
|
736
|
+
|
|
737
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
738
|
+
try:
|
|
739
|
+
text = args["text"]
|
|
740
|
+
transform_type = args["transform_type"]
|
|
741
|
+
|
|
742
|
+
# 使用PrettyOutput显示执行过程
|
|
743
|
+
PrettyOutput.print(f"正在将文本转换为 {{transform_type}} 格式...", OutputType.INFO)
|
|
744
|
+
|
|
745
|
+
if transform_type == "upper":
|
|
746
|
+
result = text.upper()
|
|
747
|
+
PrettyOutput.print("文本已转换为大写", OutputType.SUCCESS)
|
|
748
|
+
elif transform_type == "lower":
|
|
749
|
+
result = text.lower()
|
|
750
|
+
PrettyOutput.print("文本已转换为小写", OutputType.SUCCESS)
|
|
751
|
+
elif transform_type == "title":
|
|
752
|
+
result = text.title()
|
|
753
|
+
PrettyOutput.print("文本已转换为首字母大写", OutputType.SUCCESS)
|
|
754
|
+
else:
|
|
755
|
+
PrettyOutput.print(f"不支持的转换类型: {{transform_type}}", OutputType.ERROR)
|
|
756
|
+
return {{
|
|
757
|
+
"success": False,
|
|
758
|
+
"stdout": "",
|
|
759
|
+
"stderr": f"不支持的转换类型: {{transform_type}}"
|
|
760
|
+
}}
|
|
761
|
+
|
|
762
|
+
return {{
|
|
763
|
+
"success": True,
|
|
764
|
+
"stdout": result,
|
|
765
|
+
"stderr": ""
|
|
766
|
+
}}
|
|
767
|
+
|
|
768
|
+
except Exception as e:
|
|
769
|
+
PrettyOutput.print(f"转换失败: {{str(e)}}", OutputType.ERROR)
|
|
770
|
+
return {{
|
|
771
|
+
"success": False,
|
|
772
|
+
"stdout": "",
|
|
773
|
+
"stderr": f"转换失败: {{str(e)}}"
|
|
774
|
+
}}
|
|
775
|
+
```
|
|
776
|
+
|
|
777
|
+
使用方法:
|
|
778
|
+
```
|
|
779
|
+
name: text_transformer
|
|
780
|
+
arguments:
|
|
781
|
+
text: hello world
|
|
782
|
+
transform_type: upper
|
|
783
|
+
```
|
|
784
|
+
</tool_example>
|
|
785
|
+
</task_analysis>"""
|
|
786
|
+
|
|
626
787
|
self.prompt = analysis_prompt
|
|
627
788
|
with spinner.hidden():
|
|
628
789
|
response = self.model.chat_until_success(self.prompt) # type: ignore
|
|
629
790
|
|
|
630
791
|
with spinner.hidden():
|
|
631
792
|
self._call_tools(response)
|
|
632
|
-
spinner.text = "
|
|
793
|
+
spinner.text = "分析完成"
|
|
633
794
|
spinner.ok("✅")
|
|
634
795
|
except Exception as e:
|
|
635
|
-
spinner.text = "
|
|
796
|
+
spinner.text = "分析失败"
|
|
636
797
|
spinner.fail("❌")
|
|
637
798
|
if self.need_summary:
|
|
638
799
|
with yaspin(text="正在生成总结...", color="cyan") as spinner:
|
|
@@ -689,7 +850,7 @@ arguments:
|
|
|
689
850
|
if self.after_tool_call_cb:
|
|
690
851
|
self.after_tool_call_cb(self)
|
|
691
852
|
|
|
692
|
-
if self.prompt:
|
|
853
|
+
if self.prompt or self.addon_prompt:
|
|
693
854
|
continue
|
|
694
855
|
|
|
695
856
|
if self.auto_complete and ot("!!!COMPLETE!!!") in current_response:
|
jarvis/jarvis_agent/jarvis.py
CHANGED
|
@@ -395,10 +395,10 @@ class CodeAgent:
|
|
|
395
395
|
if not is_confirm_before_apply_patch() or user_confirm("是否使用此回复?", default=True):
|
|
396
396
|
agent.prompt += final_ret
|
|
397
397
|
return
|
|
398
|
+
agent.prompt += final_ret
|
|
398
399
|
custom_reply = get_multiline_input("请输入自定义回复")
|
|
399
|
-
if
|
|
400
|
-
agent.
|
|
401
|
-
agent.set_addon_prompt(custom_reply)
|
|
400
|
+
if custom_reply.strip(): # 如果自定义回复为空,返回空字符串
|
|
401
|
+
agent.set_addon_prompt(custom_reply)
|
|
402
402
|
agent.prompt += final_ret
|
|
403
403
|
|
|
404
404
|
|
|
@@ -591,8 +591,8 @@ class CodeReviewTool:
|
|
|
591
591
|
is_large_content = is_context_overflow(diff_output)
|
|
592
592
|
|
|
593
593
|
# Upload the file to the agent's model
|
|
594
|
-
|
|
595
|
-
|
|
594
|
+
if is_large_content and agent.model and hasattr(agent.model, 'upload_files'):
|
|
595
|
+
with yaspin(text="正在上传代码差异文件...", color="cyan") as spinner:
|
|
596
596
|
upload_success = agent.model.upload_files([temp_file_path])
|
|
597
597
|
if upload_success:
|
|
598
598
|
spinner.ok("✅")
|
|
@@ -600,8 +600,8 @@ class CodeReviewTool:
|
|
|
600
600
|
else:
|
|
601
601
|
spinner.fail("❌")
|
|
602
602
|
PrettyOutput.print(f"上传代码差异文件失败,将使用分块处理", OutputType.WARNING)
|
|
603
|
-
|
|
604
|
-
|
|
603
|
+
else:
|
|
604
|
+
upload_success = False
|
|
605
605
|
|
|
606
606
|
# Prepare the prompt based on upload status
|
|
607
607
|
if upload_success:
|
|
@@ -617,14 +617,15 @@ class CodeReviewTool:
|
|
|
617
617
|
# Run the agent with the prompt
|
|
618
618
|
result = agent.run(complete_prompt)
|
|
619
619
|
else:
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
620
|
+
if is_large_content:
|
|
621
|
+
return {
|
|
622
|
+
"success": False,
|
|
623
|
+
"stdout": "",
|
|
624
|
+
"stderr": "错误:上传代码差异文件失败"
|
|
625
|
+
}
|
|
626
|
+
# Include the diff directly in the prompt for smaller content
|
|
627
|
+
complete_prompt = user_prompt + "\n\n代码差异内容:\n```diff\n" + diff_output + "\n```"
|
|
628
|
+
result = agent.run(complete_prompt)
|
|
628
629
|
finally:
|
|
629
630
|
# Clean up the temporary file
|
|
630
631
|
if os.path.exists(temp_file_path):
|
|
@@ -180,11 +180,12 @@ class GitCommitTool:
|
|
|
180
180
|
'''
|
|
181
181
|
commit_message = platform.chat_until_success(prompt)
|
|
182
182
|
else:
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
183
|
+
if is_large_content:
|
|
184
|
+
return {
|
|
185
|
+
"success": False,
|
|
186
|
+
"stdout": "",
|
|
187
|
+
"stderr": "错误:上传代码差异文件失败"
|
|
188
|
+
}
|
|
188
189
|
# 直接在提示中包含差异内容
|
|
189
190
|
prompt = base_prompt + f'''
|
|
190
191
|
# 分析材料
|
jarvis/jarvis_platform/base.py
CHANGED
|
@@ -2,10 +2,12 @@
|
|
|
2
2
|
from abc import ABC, abstractmethod
|
|
3
3
|
import re
|
|
4
4
|
from typing import List, Tuple
|
|
5
|
+
|
|
6
|
+
from yaspin import yaspin
|
|
5
7
|
from jarvis.jarvis_utils.config import get_max_input_token_count
|
|
6
8
|
from jarvis.jarvis_utils.embedding import split_text_into_chunks
|
|
7
9
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
8
|
-
from jarvis.jarvis_utils.utils import get_context_token_count, while_success, while_true
|
|
10
|
+
from jarvis.jarvis_utils.utils import get_context_token_count, is_context_overflow, while_success, while_true
|
|
9
11
|
from jarvis.jarvis_utils.tag import ot, ct
|
|
10
12
|
|
|
11
13
|
|
|
@@ -38,29 +40,40 @@ class BasePlatform(ABC):
|
|
|
38
40
|
@abstractmethod
|
|
39
41
|
def upload_files(self, file_list: List[str]) -> bool:
|
|
40
42
|
raise NotImplementedError("upload_files is not implemented")
|
|
41
|
-
|
|
42
|
-
def chat_big_content(self, content: str, prompt: str) -> str:
|
|
43
|
-
# 检查content大小不超过10MB
|
|
44
|
-
if len(content.encode('utf-8')) > 10 * 1024 * 1024:
|
|
45
|
-
return "Error: Content size exceeds 10MB limit"
|
|
46
|
-
|
|
47
|
-
prefix_prompt = f"""
|
|
48
|
-
我将分多次提供大量的上下文内容,在我明确告诉你内容已经全部提供完毕之前,每次仅需要输出“已收到”。
|
|
49
|
-
"""
|
|
50
|
-
self.chat_until_success(prefix_prompt)
|
|
51
|
-
split_content = split_text_into_chunks(content, get_max_input_token_count() - 1024, get_max_input_token_count() - 2048)
|
|
52
|
-
submit_count = 0
|
|
53
|
-
for chunk in split_content:
|
|
54
|
-
submit_count += 1
|
|
55
|
-
PrettyOutput.print(f"已提交{submit_count}次(总{len(split_content)}次)", OutputType.INFO)
|
|
56
|
-
self.chat_until_success(f"<part_content>{chunk}</part_content>请返回已收到")
|
|
57
|
-
return self.chat_until_success(f"内容已经全部提供完毕\n\n{prompt}")
|
|
43
|
+
|
|
58
44
|
|
|
59
45
|
|
|
60
46
|
def _chat(self, message: str):
|
|
61
47
|
import time
|
|
62
48
|
start_time = time.time()
|
|
63
|
-
|
|
49
|
+
|
|
50
|
+
input_token_count = get_context_token_count(message)
|
|
51
|
+
|
|
52
|
+
if is_context_overflow(message):
|
|
53
|
+
PrettyOutput.print("错误:输入内容超过最大限制", OutputType.WARNING)
|
|
54
|
+
return "错误:输入内容超过最大限制"
|
|
55
|
+
|
|
56
|
+
if input_token_count > get_max_input_token_count():
|
|
57
|
+
current_suppress_output = self.suppress_output
|
|
58
|
+
self.set_suppress_output(True)
|
|
59
|
+
inputs = split_text_into_chunks(message, get_max_input_token_count() - 1024, get_max_input_token_count() - 2048)
|
|
60
|
+
with yaspin(text="正在提交长上下文...", color="cyan") as spinner:
|
|
61
|
+
prefix_prompt = f"""
|
|
62
|
+
我将分多次提供大量内容,在我明确告诉你内容已经全部提供完毕之前,每次仅需要输出“已收到”,明白请输出“开始接收输入”。
|
|
63
|
+
"""
|
|
64
|
+
while_true(lambda: while_success(lambda: self.chat(prefix_prompt), 5), 5)
|
|
65
|
+
submit_count = 0
|
|
66
|
+
for input in inputs:
|
|
67
|
+
submit_count += 1
|
|
68
|
+
spinner.text = f"正在提交第{submit_count}部分(共{len(inputs)}部分)"
|
|
69
|
+
while_true(lambda: while_success(lambda: self.chat(f"<part_content>{input}</part_content>请返回已收到"), 5), 5)
|
|
70
|
+
spinner.text = "提交完成"
|
|
71
|
+
spinner.ok("✅")
|
|
72
|
+
self.set_suppress_output(current_suppress_output)
|
|
73
|
+
response = while_true(lambda: while_success(lambda: self.chat("内容已经全部提供完毕,请继续"), 5), 5)
|
|
74
|
+
|
|
75
|
+
else:
|
|
76
|
+
response = self.chat(message)
|
|
64
77
|
|
|
65
78
|
end_time = time.time()
|
|
66
79
|
duration = end_time - start_time
|
|
@@ -78,7 +91,7 @@ class BasePlatform(ABC):
|
|
|
78
91
|
# Print statistics
|
|
79
92
|
if not self.suppress_output:
|
|
80
93
|
PrettyOutput.print(
|
|
81
|
-
f"对话完成 - 耗时: {duration:.2f}秒, 输出字符数: {char_count}, 输出Token数量: {token_count}, 每秒Token数量: {tokens_per_second:.2f}",
|
|
94
|
+
f"对话完成 - 耗时: {duration:.2f}秒, 输入字符数: {len(message)}, 输入Token数量: {input_token_count}, 输出字符数: {char_count}, 输出Token数量: {token_count}, 每秒Token数量: {tokens_per_second:.2f}",
|
|
82
95
|
OutputType.INFO,
|
|
83
96
|
)
|
|
84
97
|
|
jarvis/jarvis_tools/edit_file.py
CHANGED
|
@@ -23,6 +23,7 @@ from yaspin import yaspin
|
|
|
23
23
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
24
24
|
from jarvis.jarvis_tools.file_operation import FileOperationTool
|
|
25
25
|
from jarvis.jarvis_utils.git_utils import revert_file
|
|
26
|
+
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
26
27
|
from jarvis.jarvis_utils.tag import ct, ot
|
|
27
28
|
from jarvis.jarvis_utils.utils import is_context_overflow
|
|
28
29
|
|
|
@@ -230,6 +231,11 @@ def patch_apply(filepath: str, patch_content: str) -> Tuple[bool, str]:
|
|
|
230
231
|
2. 失败时自动回滚文件修改
|
|
231
232
|
3. 提供详细的执行状态输出
|
|
232
233
|
"""
|
|
234
|
+
import os
|
|
235
|
+
work_dir = os.path.abspath(os.curdir)
|
|
236
|
+
filepath = os.path.abspath(filepath)
|
|
237
|
+
if not filepath.startswith(work_dir):
|
|
238
|
+
PrettyOutput.print(f"文件 {filepath} 不在工作目录 {work_dir} 下,不会进行版本控制管理", OutputType.WARNING)
|
|
233
239
|
model = PlatformRegistry().get_normal_platform()
|
|
234
240
|
with yaspin(text=f"正在处理文件 {filepath}...", color="cyan") as spinner:
|
|
235
241
|
try:
|
|
@@ -300,7 +306,7 @@ def patch_apply(filepath: str, patch_content: str) -> Tuple[bool, str]:
|
|
|
300
306
|
if upload_success:
|
|
301
307
|
response = model.chat_until_success(main_prompt)
|
|
302
308
|
else:
|
|
303
|
-
|
|
309
|
+
return False, ""
|
|
304
310
|
|
|
305
311
|
# 解析差异化补丁
|
|
306
312
|
diff_blocks = re.finditer(ot("DIFF")+r'\s*>{4,} SEARCH\n?(.*?)\n?={4,}\n?(.*?)\s*<{4,} REPLACE\n?'+ct("DIFF"),
|
|
@@ -12,85 +12,6 @@ class generate_new_tool:
|
|
|
12
12
|
生成并注册新的Jarvis工具。该工具会在用户数据目录下创建新的工具文件,
|
|
13
13
|
并自动注册到当前的工具注册表中。适用场景:1. 需要创建新的自定义工具;
|
|
14
14
|
2. 扩展Jarvis功能;3. 自动化重复性操作;4. 封装特定领域的功能。
|
|
15
|
-
|
|
16
|
-
使用示例:
|
|
17
|
-
|
|
18
|
-
```
|
|
19
|
-
# 创建一个将文本转换为大写/小写的工具
|
|
20
|
-
name: generate_new_tool
|
|
21
|
-
arguments:
|
|
22
|
-
tool_name: text_transformer
|
|
23
|
-
tool_code: |
|
|
24
|
-
# -*- coding: utf-8 -*-
|
|
25
|
-
from typing import Dict, Any
|
|
26
|
-
|
|
27
|
-
class text_transformer:
|
|
28
|
-
name = "text_transformer"
|
|
29
|
-
description = \"\"\"
|
|
30
|
-
文本转换工具,可以将输入的文本转换为大写、小写或首字母大写格式。
|
|
31
|
-
适用场景:1. 格式化文本; 2. 处理标题; 3. 标准化输出
|
|
32
|
-
\"\"\"
|
|
33
|
-
|
|
34
|
-
parameters = {
|
|
35
|
-
"type": "object",
|
|
36
|
-
"properties": {
|
|
37
|
-
"text": {
|
|
38
|
-
"type": "string",
|
|
39
|
-
"description": "需要转换格式的文本"
|
|
40
|
-
},
|
|
41
|
-
"transform_type": {
|
|
42
|
-
"type": "string",
|
|
43
|
-
"description": "转换类型,可选值为 upper(大写)、lower(小写)或 title(首字母大写)",
|
|
44
|
-
"enum": ["upper", "lower", "title"]
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
"required": ["text", "transform_type"]
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
@staticmethod
|
|
51
|
-
def check() -> bool:
|
|
52
|
-
return True
|
|
53
|
-
|
|
54
|
-
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
55
|
-
try:
|
|
56
|
-
text = args["text"]
|
|
57
|
-
transform_type = args["transform_type"]
|
|
58
|
-
|
|
59
|
-
if transform_type == "upper":
|
|
60
|
-
result = text.upper()
|
|
61
|
-
elif transform_type == "lower":
|
|
62
|
-
result = text.lower()
|
|
63
|
-
elif transform_type == "title":
|
|
64
|
-
result = text.title()
|
|
65
|
-
else:
|
|
66
|
-
return {
|
|
67
|
-
"success": False,
|
|
68
|
-
"stdout": "",
|
|
69
|
-
"stderr": f"不支持的转换类型: {transform_type}"
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
return {
|
|
73
|
-
"success": True,
|
|
74
|
-
"stdout": result,
|
|
75
|
-
"stderr": ""
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
except Exception as e:
|
|
79
|
-
return {
|
|
80
|
-
"success": False,
|
|
81
|
-
"stdout": "",
|
|
82
|
-
"stderr": f"转换失败: {str(e)}"
|
|
83
|
-
}
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
创建完成后可以立即使用:
|
|
87
|
-
|
|
88
|
-
```
|
|
89
|
-
name: text_transformer
|
|
90
|
-
arguments:
|
|
91
|
-
text: hello world
|
|
92
|
-
transform_type: upper
|
|
93
|
-
```
|
|
94
15
|
"""
|
|
95
16
|
|
|
96
17
|
parameters = {
|
|
@@ -136,6 +57,7 @@ class generate_new_tool:
|
|
|
136
57
|
返回:
|
|
137
58
|
Dict: 包含生成结果的字典
|
|
138
59
|
"""
|
|
60
|
+
tool_file_path = None
|
|
139
61
|
try:
|
|
140
62
|
# 从参数中获取工具信息
|
|
141
63
|
tool_name = args["tool_name"]
|
|
@@ -181,15 +103,30 @@ class generate_new_tool:
|
|
|
181
103
|
# 注册新工具到当前的工具注册表
|
|
182
104
|
success_message = f"工具 '{tool_name}' 已成功生成在 {tool_file_path}"
|
|
183
105
|
|
|
106
|
+
registration_successful = False
|
|
184
107
|
if agent:
|
|
185
108
|
tool_registry = agent.get_tool_registry()
|
|
186
109
|
if tool_registry:
|
|
187
110
|
# 尝试加载并注册新工具
|
|
111
|
+
PrettyOutput.print(f"正在注册工具 '{tool_name}'...", OutputType.INFO)
|
|
188
112
|
if tool_registry.register_tool_by_file(str(tool_file_path)):
|
|
189
113
|
success_message += f"\n已成功注册到当前会话的工具注册表中"
|
|
114
|
+
registration_successful = True
|
|
115
|
+
else:
|
|
116
|
+
# 注册失败,删除已创建的文件
|
|
117
|
+
PrettyOutput.print(f"注册工具 '{tool_name}' 失败,正在删除文件...", OutputType.WARNING)
|
|
118
|
+
if tool_file_path.exists():
|
|
119
|
+
tool_file_path.unlink()
|
|
120
|
+
return {
|
|
121
|
+
"success": False,
|
|
122
|
+
"stdout": "",
|
|
123
|
+
"stderr": f"工具文件已生成,但注册失败。文件已被删除。"
|
|
124
|
+
}
|
|
190
125
|
else:
|
|
126
|
+
PrettyOutput.print("未找到工具注册表,无法自动注册工具", OutputType.WARNING)
|
|
191
127
|
success_message += f"\n注册到当前会话失败,可能需要重新启动Jarvis"
|
|
192
128
|
|
|
129
|
+
PrettyOutput.print(f"工具 '{tool_name}' 创建" + ("并注册" if registration_successful else "") + "成功!", OutputType.SUCCESS)
|
|
193
130
|
return {
|
|
194
131
|
"success": True,
|
|
195
132
|
"stdout": success_message,
|
|
@@ -197,11 +134,23 @@ class generate_new_tool:
|
|
|
197
134
|
}
|
|
198
135
|
|
|
199
136
|
except Exception as e:
|
|
200
|
-
#
|
|
137
|
+
# 如果发生异常,删除已创建的文件并返回失败响应
|
|
138
|
+
error_msg = f"生成工具失败: {str(e)}"
|
|
139
|
+
PrettyOutput.print(error_msg, OutputType.ERROR)
|
|
140
|
+
|
|
141
|
+
# 删除已创建的文件
|
|
142
|
+
if tool_file_path and tool_file_path.exists():
|
|
143
|
+
try:
|
|
144
|
+
PrettyOutput.print(f"正在删除已创建的文件 {tool_file_path}...", OutputType.INFO)
|
|
145
|
+
tool_file_path.unlink()
|
|
146
|
+
PrettyOutput.print(f"文件已删除", OutputType.SUCCESS)
|
|
147
|
+
except Exception as delete_error:
|
|
148
|
+
PrettyOutput.print(f"删除文件失败: {str(delete_error)}", OutputType.ERROR)
|
|
149
|
+
|
|
201
150
|
return {
|
|
202
151
|
"success": False,
|
|
203
152
|
"stdout": "",
|
|
204
|
-
"stderr":
|
|
153
|
+
"stderr": error_msg
|
|
205
154
|
}
|
|
206
155
|
|
|
207
156
|
def _validate_and_process_code(self, tool_name: str, tool_code: str) -> Tuple[str, str]:
|
jarvis/jarvis_tools/registry.py
CHANGED
|
@@ -636,12 +636,8 @@ class ToolRegistry(OutputHandler):
|
|
|
636
636
|
return f"""工具调用原始输出过长,以下是根据输出提出的信息:
|
|
637
637
|
|
|
638
638
|
{platform.chat_until_success(prompt)}"""
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
prompt = f"以下内容为工具执行结果,请阅读内容,并根据内容提取出以下信息:{want}\n\n{output}"
|
|
642
|
-
return f"""工具调用原始输出过长,以下是根据输出提出的信息:
|
|
643
|
-
|
|
644
|
-
{platform.chat_big_content(output, prompt)}"""
|
|
639
|
+
else:
|
|
640
|
+
return self._truncate_output(output)
|
|
645
641
|
|
|
646
642
|
# 如果都不支持,返回截断的输出
|
|
647
643
|
return self._truncate_output(output)
|
jarvis/jarvis_utils/config.py
CHANGED
|
@@ -151,4 +151,13 @@ def get_auto_update() -> bool:
|
|
|
151
151
|
返回:
|
|
152
152
|
bool: 如果需要自动更新则返回True,默认为True
|
|
153
153
|
"""
|
|
154
|
-
return os.getenv('JARVIS_AUTO_UPDATE', 'true') == 'true'
|
|
154
|
+
return os.getenv('JARVIS_AUTO_UPDATE', 'true') == 'true'
|
|
155
|
+
|
|
156
|
+
def get_max_big_content_size() -> int:
|
|
157
|
+
"""
|
|
158
|
+
获取最大大内容大小。
|
|
159
|
+
|
|
160
|
+
返回:
|
|
161
|
+
int: 最大大内容大小,默认为1MB
|
|
162
|
+
"""
|
|
163
|
+
return int(os.getenv('JARVIS_MAX_BIG_CONTENT_SIZE', '163840'))
|
|
@@ -125,6 +125,7 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
|
125
125
|
|
|
126
126
|
# 获取当前平台
|
|
127
127
|
platform = PlatformRegistry().get_normal_platform()
|
|
128
|
+
platform.set_suppress_output(False)
|
|
128
129
|
if not platform:
|
|
129
130
|
return ""
|
|
130
131
|
|
|
@@ -175,7 +176,6 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
|
175
176
|
|
|
176
177
|
# 尝试上传文件
|
|
177
178
|
if hasattr(platform, 'upload_files'):
|
|
178
|
-
platform.set_suppress_output(False)
|
|
179
179
|
upload_success = platform.upload_files([temp_file_path])
|
|
180
180
|
|
|
181
181
|
if upload_success:
|
|
@@ -195,24 +195,8 @@ def load_methodology(user_input: str, tool_registery: Optional[Any] = None) -> s
|
|
|
195
195
|
如果没有匹配的方法论,请输出:没有历史方法论可参考
|
|
196
196
|
除以上要求外,不要输出任何内容
|
|
197
197
|
""")
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
return platform.chat_big_content(full_content, base_prompt + f"""
|
|
201
|
-
请根据以上方法论和可调用的工具文件内容,规划/总结出以下用户需求的执行步骤: {user_input}
|
|
202
|
-
|
|
203
|
-
请按以下格式回复:
|
|
204
|
-
### 与该任务/需求相关的方法论
|
|
205
|
-
1. [方法论名字]
|
|
206
|
-
2. [方法论名字]
|
|
207
|
-
### 根据以上方法论,规划/总结出执行步骤
|
|
208
|
-
1. [步骤1]
|
|
209
|
-
2. [步骤2]
|
|
210
|
-
3. [步骤3]
|
|
211
|
-
|
|
212
|
-
如果没有匹配的方法论,请输出:没有历史方法论可参考
|
|
213
|
-
除以上要求外,不要输出任何内容
|
|
214
|
-
""")
|
|
215
|
-
|
|
198
|
+
else:
|
|
199
|
+
return "没有历史方法论可参考"
|
|
216
200
|
# 如果内容不大或上传失败,直接使用chat_until_success
|
|
217
201
|
return platform.chat_until_success(full_content)
|
|
218
202
|
|
jarvis/jarvis_utils/utils.py
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
# -*- coding: utf-8 -*-
|
|
2
|
-
from doctest import script_from_examples
|
|
3
2
|
import os
|
|
4
3
|
import time
|
|
5
4
|
import hashlib
|
|
6
5
|
import tarfile
|
|
7
6
|
from pathlib import Path
|
|
8
|
-
from typing import
|
|
9
|
-
from jarvis.jarvis_utils.config import
|
|
7
|
+
from typing import Any, Callable
|
|
8
|
+
from jarvis.jarvis_utils.config import get_max_big_content_size, get_data_dir
|
|
10
9
|
from jarvis.jarvis_utils.embedding import get_context_token_count
|
|
11
10
|
from jarvis.jarvis_utils.input import get_single_line_input
|
|
12
11
|
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
@@ -125,37 +124,7 @@ def get_file_line_count(filename: str) -> int:
|
|
|
125
124
|
return 0
|
|
126
125
|
|
|
127
126
|
|
|
128
|
-
def is_long_context(files: List[str]) -> bool:
|
|
129
|
-
"""检查文件列表是否属于长上下文
|
|
130
127
|
|
|
131
|
-
|
|
132
|
-
当总token数超过最大上下文长度的80%时视为长上下文
|
|
133
|
-
|
|
134
|
-
参数:
|
|
135
|
-
files -- 要检查的文件路径列表
|
|
136
|
-
|
|
137
|
-
返回:
|
|
138
|
-
布尔值表示是否属于长上下文
|
|
139
|
-
"""
|
|
140
|
-
max_input_token_count = get_max_input_token_count()
|
|
141
|
-
threshold = max_input_token_count * 0.8
|
|
142
|
-
total_tokens = 0
|
|
143
|
-
|
|
144
|
-
for file_path in files:
|
|
145
|
-
try:
|
|
146
|
-
with open(file_path, 'r', encoding='utf-8', errors="ignore") as f:
|
|
147
|
-
content = f.read()
|
|
148
|
-
total_tokens += get_context_token_count(content)
|
|
149
|
-
|
|
150
|
-
if total_tokens > threshold:
|
|
151
|
-
return True
|
|
152
|
-
except Exception as e:
|
|
153
|
-
PrettyOutput.print(f"读取文件 {file_path} 失败: {e}", OutputType.WARNING)
|
|
154
|
-
continue
|
|
155
|
-
|
|
156
|
-
return total_tokens > threshold
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
def is_context_overflow(file_content: str) -> bool:
|
|
128
|
+
def is_context_overflow(content: str) -> bool:
|
|
160
129
|
"""判断文件内容是否超出上下文限制"""
|
|
161
|
-
return get_context_token_count(
|
|
130
|
+
return get_context_token_count(content) > get_max_big_content_size()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jarvis-ai-assistant
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.171
|
|
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
|
|
@@ -213,6 +213,7 @@ OPENAI_API_BASE=https://api.openai.com/v1 # 可选,默认为官方API地址
|
|
|
213
213
|
| `JARVIS_CONFIRM_BEFORE_APPLY_PATCH` | true | 应用补丁前是否需要确认 |
|
|
214
214
|
| `JARVIS_MAX_TOOL_CALL_COUNT` | 20 | 最大连续工具调用次数 |
|
|
215
215
|
| `JARVIS_AUTO_UPDATE` | true | 是否自动更新Jarvis(仅在以git仓库方式安装时有效) |
|
|
216
|
+
| `JARVIS_MAX_BIG_CONTENT_SIZE` | 10485760 | 最大大内容大小 |
|
|
216
217
|
|
|
217
218
|
所有配置编写到`~/.jarvis/env`文件中即可生效。
|
|
218
219
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
jarvis/__init__.py,sha256=
|
|
2
|
-
jarvis/jarvis_agent/__init__.py,sha256=
|
|
1
|
+
jarvis/__init__.py,sha256=VnCd0RxDGsMy-0sOoD8gB7obLOpzOBEThebur7vlvxI,74
|
|
2
|
+
jarvis/jarvis_agent/__init__.py,sha256=J3teZnIgaGqztT3qgtyZA-zYJHKzK6NsyMNDlCKKChU,31045
|
|
3
3
|
jarvis/jarvis_agent/builtin_input_handler.py,sha256=KhvlV_QdB3P-M0TCkWvdxidNie1jU7KoMOqTIXCpwwA,1529
|
|
4
4
|
jarvis/jarvis_agent/file_input_handler.py,sha256=EwaitWczbwLCKNpWU9C7m829_G5uLZ_hNcVXlX2ANes,3437
|
|
5
|
-
jarvis/jarvis_agent/jarvis.py,sha256=
|
|
5
|
+
jarvis/jarvis_agent/jarvis.py,sha256=IuM-A9KZd1jqOFszB2l-Ua1FE5uVGvvNia1SSgp7Jgg,5963
|
|
6
6
|
jarvis/jarvis_agent/main.py,sha256=IAD59fEMWWSSAtHJhOQMPs_NMoKtcYjrxlTvhCHEVII,2626
|
|
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
|
|
10
|
-
jarvis/jarvis_code_agent/code_agent.py,sha256=
|
|
11
|
-
jarvis/jarvis_code_analysis/code_review.py,sha256=
|
|
10
|
+
jarvis/jarvis_code_agent/code_agent.py,sha256=vN-HZcwMnOfofq5JDjuVADQdBRdG1SuRv_-_BkKUUQI,16855
|
|
11
|
+
jarvis/jarvis_code_analysis/code_review.py,sha256=68GCjxdg-n2hoMoCSGWpH_ZdQArc4G09E9Wwhypk4eY,30135
|
|
12
12
|
jarvis/jarvis_code_analysis/checklists/__init__.py,sha256=cKQ_FOGy5TQgM-YkRCqORo-mUOZaPAJ9VDmZoFX58us,78
|
|
13
13
|
jarvis/jarvis_code_analysis/checklists/c_cpp.py,sha256=SXPpYCNeCtU1PpKdKPiYDuOybfY9vaL0ejDn4imxDwA,1317
|
|
14
14
|
jarvis/jarvis_code_analysis/checklists/csharp.py,sha256=vS-cu6RCGg5SyK9MJ3RE381gt3xYl-yea3Bj2UQEcwQ,2420
|
|
@@ -35,7 +35,7 @@ jarvis/jarvis_git_details/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
|
|
|
35
35
|
jarvis/jarvis_git_details/main.py,sha256=l4Ol96DFISq2ctAgzmfUuS4i6JdWh0JAu_isY3iuzVo,8919
|
|
36
36
|
jarvis/jarvis_git_squash/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
37
|
jarvis/jarvis_git_squash/main.py,sha256=uZf05Y7UN8kwlrfsSeX2NEGCaowwzZsm9LqjgmQxeic,2203
|
|
38
|
-
jarvis/jarvis_git_utils/git_commiter.py,sha256=
|
|
38
|
+
jarvis/jarvis_git_utils/git_commiter.py,sha256=B9qYArFdv6Vr82__Ji_USvXYhJgGsW2v0pkUoymiwHI,12943
|
|
39
39
|
jarvis/jarvis_lsp/base.py,sha256=ZngrQ4NUy9iPrXORcw4QR-tWZi2G79nsfqeqqkaxSZ0,2054
|
|
40
40
|
jarvis/jarvis_lsp/cpp.py,sha256=WL7rItrwFkYRSZzQHnoOoQ-EDho7Jd6BOaCn1UgsQ3A,3165
|
|
41
41
|
jarvis/jarvis_lsp/go.py,sha256=FkBJAeJex8jamn44o_cpYCygSTGMnsykJGrnkVFlTww,3482
|
|
@@ -49,7 +49,7 @@ jarvis/jarvis_methodology/main.py,sha256=_KDGEQw6j_VZ9O8eDe-c8F84zl6JrKmsNRva9PG
|
|
|
49
49
|
jarvis/jarvis_multi_agent/__init__.py,sha256=LEJofDjh80U34RyZv2ECAzpt2zkhA0Jn3KZh-ABoAKA,4343
|
|
50
50
|
jarvis/jarvis_multi_agent/main.py,sha256=Z6N5VMjzaernnRjPkqgYRv09cIhWIFQ6a__AqHA8xrQ,1567
|
|
51
51
|
jarvis/jarvis_platform/__init__.py,sha256=0YnsUoM4JkIBOtImFdjfuDbrqQZT3dEaAwSJ62DrpCc,104
|
|
52
|
-
jarvis/jarvis_platform/base.py,sha256=
|
|
52
|
+
jarvis/jarvis_platform/base.py,sha256=cppBTsnQRppKRHdrwxoeiEXJYXdtsNnt4GjbF_kw-PM,5335
|
|
53
53
|
jarvis/jarvis_platform/human.py,sha256=0sbEhST4rKKGGV45dAdJqvVBnRPPeCe6HqxR245S4Z8,2462
|
|
54
54
|
jarvis/jarvis_platform/kimi.py,sha256=yz7OVT54YDSUVuFlijDB7VdsJmtqRgj-qYKPHy8f0WQ,16787
|
|
55
55
|
jarvis/jarvis_platform/openai.py,sha256=8enxCISjHtCs0qoqEag68v68m_clKr7jgEpUA0CyUBo,4139
|
|
@@ -67,35 +67,35 @@ jarvis/jarvis_tools/chdir.py,sha256=wYVBqWF5kaUkKqH3cUAOKUsACzYsFtCCJJyd8UJsp4o,
|
|
|
67
67
|
jarvis/jarvis_tools/code_plan.py,sha256=EzLdbJnVCkJ7lL8XIQyuDJdxU1i3CFiBpqyNG-GdJw8,7753
|
|
68
68
|
jarvis/jarvis_tools/create_code_agent.py,sha256=cxYkjr4rhI2EWpK78psZSRB9mxiP1IUT0SEfFIqCJzY,3411
|
|
69
69
|
jarvis/jarvis_tools/create_sub_agent.py,sha256=ppTOFRd0ygSJUFr3oQ8IrCLOqbZ7vwnbdadfTDjpDgs,3025
|
|
70
|
-
jarvis/jarvis_tools/edit_file.py,sha256=
|
|
70
|
+
jarvis/jarvis_tools/edit_file.py,sha256=8Yesy3MIPOIyz0GQph-x5G0P0hlsC-ds5T0eRPAHUQ4,14122
|
|
71
71
|
jarvis/jarvis_tools/execute_script.py,sha256=cc0NlPwhkZinEexqT63d1ofEkzQddVWGsZOCVL1v_60,5739
|
|
72
72
|
jarvis/jarvis_tools/file_analyzer.py,sha256=tzU1cPKyDa54hVZewP0bDzdsjvdjGQ1BRt5k8N4li3s,4868
|
|
73
73
|
jarvis/jarvis_tools/file_operation.py,sha256=lP8EpsnSdA3FW8ofSAdoA8qPGMAG3UhYd6LFEzOFUVY,9044
|
|
74
74
|
jarvis/jarvis_tools/find_methodology.py,sha256=FwGKSV4fHNkiAnaVUwP8GkqXl8PEqMPZBxAyvTSPFGA,2438
|
|
75
|
-
jarvis/jarvis_tools/generate_new_tool.py,sha256=
|
|
75
|
+
jarvis/jarvis_tools/generate_new_tool.py,sha256=ctpkHBihsHhO6sLpF5lJue244EFJtdEQMuxR-_oV9r4,10282
|
|
76
76
|
jarvis/jarvis_tools/lsp_get_diagnostics.py,sha256=paz1CVZ2Y8nk0U74n1QiG01oDINiZqpVlPc2f4_B150,5346
|
|
77
77
|
jarvis/jarvis_tools/methodology.py,sha256=Md8W2et0xUiuTjUSRCdnlwEPYqah2dCAAkxW_95BXBY,5238
|
|
78
78
|
jarvis/jarvis_tools/read_code.py,sha256=pgztSBRh8RORFalqwzzsLHQogooFvDm1ePBL0E5O1C4,5961
|
|
79
79
|
jarvis/jarvis_tools/read_webpage.py,sha256=LLvAOvaQJodaeNJKQ6dU9MYEE227NMdHyLs7esluUQ4,2217
|
|
80
|
-
jarvis/jarvis_tools/registry.py,sha256=
|
|
80
|
+
jarvis/jarvis_tools/registry.py,sha256=9Rr8F0lfsvSlFZ_X8yQ8XPohB_Jg7mYutTB1tq9TJHw,26750
|
|
81
81
|
jarvis/jarvis_tools/rewrite_file.py,sha256=rEPPSNU7uF1iKfEW9npEpZJ2LSoQXjt2OC-_troBToE,7003
|
|
82
82
|
jarvis/jarvis_tools/search_web.py,sha256=-h1WYOqTcYC_8fdkm-4RfwKpbtLTVxOfRROul51NgO0,951
|
|
83
83
|
jarvis/jarvis_tools/virtual_tty.py,sha256=AKAaKY5KcPxifNQoXjzHaL4U6EUVA7irHLwVvz2wLVs,16396
|
|
84
84
|
jarvis/jarvis_utils/__init__.py,sha256=l-fsyQ-KzyqAhrJYur8eZAqsgaifGzSm24R2qtRGJ0g,849
|
|
85
85
|
jarvis/jarvis_utils/builtin_replace_map.py,sha256=A-cJ8deht2vDl2iKRhoZ7qECyJ6sboVH5Zx-L9vIBUs,4314
|
|
86
|
-
jarvis/jarvis_utils/config.py,sha256
|
|
86
|
+
jarvis/jarvis_utils/config.py,sha256=-x66P2PY8Ne02W1Yg0vofcMlErJq1Y99C5Sc6_n6Cv8,4538
|
|
87
87
|
jarvis/jarvis_utils/embedding.py,sha256=05KvmZvtI2-7xxmj13kAknRezWuVeold-D68wyPvZSA,7015
|
|
88
88
|
jarvis/jarvis_utils/file_processors.py,sha256=tSZSMJ4qCJ_lXI0dyLgJ0j5qEh6CDXDSVI7vQiFmcuQ,2976
|
|
89
89
|
jarvis/jarvis_utils/git_utils.py,sha256=MxhUcQ_gFUFyBxBiorEJ1wUk9a2TerFdq3-Z11FB-AE,11324
|
|
90
90
|
jarvis/jarvis_utils/globals.py,sha256=Zs0chxA_giYiolYvawFFpcnTWgCUnn6GEusAh42jbz8,2275
|
|
91
91
|
jarvis/jarvis_utils/input.py,sha256=qGf2q-yWhgT-OX-j_WYi7aZ11jYmuFNiMz2_W1nUOiM,7432
|
|
92
|
-
jarvis/jarvis_utils/methodology.py,sha256=
|
|
92
|
+
jarvis/jarvis_utils/methodology.py,sha256=P1S_J9zxTed0Unpj0r-w14zpj8lEe_3bXgq1uvojjdQ,7512
|
|
93
93
|
jarvis/jarvis_utils/output.py,sha256=PVG4fQ3P-eGOZUNZTowPtnjqq3GN91OE8fHa68lFOOg,8440
|
|
94
94
|
jarvis/jarvis_utils/tag.py,sha256=YJHmuedLb7_AiqvKQetHr4R1FxyzIh7HN0RRkWMmYbU,429
|
|
95
|
-
jarvis/jarvis_utils/utils.py,sha256=
|
|
96
|
-
jarvis_ai_assistant-0.1.
|
|
97
|
-
jarvis_ai_assistant-0.1.
|
|
98
|
-
jarvis_ai_assistant-0.1.
|
|
99
|
-
jarvis_ai_assistant-0.1.
|
|
100
|
-
jarvis_ai_assistant-0.1.
|
|
101
|
-
jarvis_ai_assistant-0.1.
|
|
95
|
+
jarvis/jarvis_utils/utils.py,sha256=iIcefLa1kvALkmQ19BLWDplmxrcOjtxWAgBIxrs8ytg,4439
|
|
96
|
+
jarvis_ai_assistant-0.1.171.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
|
97
|
+
jarvis_ai_assistant-0.1.171.dist-info/METADATA,sha256=E1RImbgBwVokaITcf4AY5HxorOnwMihvWs063pBrorE,14546
|
|
98
|
+
jarvis_ai_assistant-0.1.171.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
|
99
|
+
jarvis_ai_assistant-0.1.171.dist-info/entry_points.txt,sha256=cKz_9SEpOvElTubKPMZMAdskD4GHz-NyKWRNssIVAWE,973
|
|
100
|
+
jarvis_ai_assistant-0.1.171.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
|
101
|
+
jarvis_ai_assistant-0.1.171.dist-info/RECORD,,
|
|
File without changes
|
{jarvis_ai_assistant-0.1.168.dist-info → jarvis_ai_assistant-0.1.171.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.168.dist-info → jarvis_ai_assistant-0.1.171.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.168.dist-info → jarvis_ai_assistant-0.1.171.dist-info}/top_level.txt
RENAMED
|
File without changes
|