jarvis-ai-assistant 0.1.176__py3-none-any.whl → 0.1.178__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 +33 -62
- jarvis/jarvis_agent/jarvis.py +10 -10
- jarvis/jarvis_agent/main.py +6 -6
- jarvis/jarvis_code_agent/code_agent.py +10 -6
- jarvis/jarvis_code_analysis/code_review.py +1 -1
- jarvis/jarvis_dev/main.py +1 -1
- jarvis/jarvis_event/__init__.py +0 -0
- jarvis/jarvis_git_details/main.py +1 -1
- jarvis/jarvis_git_squash/main.py +1 -1
- jarvis/jarvis_git_utils/git_commiter.py +1 -1
- jarvis/jarvis_multi_agent/main.py +1 -1
- jarvis/jarvis_platform/base.py +6 -3
- jarvis/jarvis_platform/openai.py +66 -10
- jarvis/jarvis_platform/yuanbao.py +1 -1
- jarvis/jarvis_platform_manager/main.py +1 -1
- jarvis/jarvis_smart_shell/main.py +4 -2
- jarvis/jarvis_tools/ask_codebase.py +3 -2
- jarvis/jarvis_tools/cli/main.py +28 -1
- jarvis/jarvis_tools/edit_file.py +186 -118
- jarvis/jarvis_tools/read_code.py +0 -2
- jarvis/jarvis_tools/registry.py +31 -1
- jarvis/jarvis_utils/config.py +13 -4
- jarvis/jarvis_utils/output.py +36 -7
- jarvis/jarvis_utils/utils.py +19 -1
- {jarvis_ai_assistant-0.1.176.dist-info → jarvis_ai_assistant-0.1.178.dist-info}/METADATA +4 -4
- {jarvis_ai_assistant-0.1.176.dist-info → jarvis_ai_assistant-0.1.178.dist-info}/RECORD +31 -37
- {jarvis_ai_assistant-0.1.176.dist-info → jarvis_ai_assistant-0.1.178.dist-info}/WHEEL +1 -1
- jarvis/jarvis_lsp/base.py +0 -66
- jarvis/jarvis_lsp/cpp.py +0 -99
- jarvis/jarvis_lsp/go.py +0 -104
- jarvis/jarvis_lsp/python.py +0 -58
- jarvis/jarvis_lsp/registry.py +0 -169
- jarvis/jarvis_lsp/rust.py +0 -107
- jarvis/jarvis_tools/lsp_get_diagnostics.py +0 -147
- {jarvis_ai_assistant-0.1.176.dist-info → jarvis_ai_assistant-0.1.178.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.176.dist-info → jarvis_ai_assistant-0.1.178.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.176.dist-info → jarvis_ai_assistant-0.1.178.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
|
@@ -10,7 +10,7 @@ from jarvis.jarvis_platform.base import BasePlatform
|
|
|
10
10
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
11
11
|
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
12
12
|
from jarvis.jarvis_utils.embedding import get_context_token_count
|
|
13
|
-
from jarvis.jarvis_utils.config import get_max_tool_call_count, is_auto_complete, is_execute_tool_confirm
|
|
13
|
+
from jarvis.jarvis_utils.config import get_max_tool_call_count, is_auto_complete, is_execute_tool_confirm, is_use_methodology
|
|
14
14
|
from jarvis.jarvis_utils.methodology import load_methodology, upload_methodology
|
|
15
15
|
from jarvis.jarvis_utils.globals import make_agent_name, set_agent, delete_agent
|
|
16
16
|
from jarvis.jarvis_utils.input import get_multiline_input
|
|
@@ -150,7 +150,8 @@ class Agent:
|
|
|
150
150
|
input_handler: Optional[List[Callable[[str, Any], Tuple[str, bool]]]] = None,
|
|
151
151
|
execute_tool_confirm: Optional[bool] = None,
|
|
152
152
|
need_summary: bool = True,
|
|
153
|
-
multiline_inputer: Optional[Callable[[str], str]] = None
|
|
153
|
+
multiline_inputer: Optional[Callable[[str], str]] = None,
|
|
154
|
+
use_methodology: Optional[bool] = None):
|
|
154
155
|
"""初始化Jarvis Agent实例
|
|
155
156
|
|
|
156
157
|
参数:
|
|
@@ -167,6 +168,7 @@ class Agent:
|
|
|
167
168
|
execute_tool_confirm: 执行工具前是否需要确认
|
|
168
169
|
need_summary: 是否需要生成总结
|
|
169
170
|
multiline_inputer: 多行输入处理器
|
|
171
|
+
use_methodology: 是否使用方法论
|
|
170
172
|
"""
|
|
171
173
|
self.name = make_agent_name(name)
|
|
172
174
|
self.description = description
|
|
@@ -193,6 +195,8 @@ class Agent:
|
|
|
193
195
|
|
|
194
196
|
self.multiline_inputer = multiline_inputer if multiline_inputer else get_multiline_input
|
|
195
197
|
|
|
198
|
+
self.use_methodology = use_methodology if use_methodology is not None else is_use_methodology()
|
|
199
|
+
|
|
196
200
|
self.prompt = ""
|
|
197
201
|
self.conversation_length = 0 # Use length counter instead
|
|
198
202
|
self.system_prompt = system_prompt
|
|
@@ -266,29 +270,12 @@ class Agent:
|
|
|
266
270
|
5. 如果对操作使用不清楚,请请求帮助
|
|
267
271
|
</rules>
|
|
268
272
|
</actions>
|
|
269
|
-
"""
|
|
270
|
-
|
|
271
|
-
complete_prompt = ""
|
|
272
|
-
if self.auto_complete:
|
|
273
|
-
complete_prompt = f"""
|
|
274
|
-
<completion>
|
|
275
|
-
<instruction>
|
|
276
|
-
## 任务完成
|
|
277
|
-
当任务完成时,你应该打印以下信息:
|
|
278
|
-
</instruction>
|
|
279
|
-
|
|
280
|
-
<marker>
|
|
281
|
-
{ot("!!!COMPLETE!!!")}
|
|
282
|
-
</marker>
|
|
283
|
-
</completion>
|
|
284
273
|
"""
|
|
285
274
|
|
|
286
275
|
self.model.set_system_message(f"""
|
|
287
276
|
{self.system_prompt}
|
|
288
277
|
|
|
289
278
|
{action_prompt}
|
|
290
|
-
|
|
291
|
-
{complete_prompt}
|
|
292
279
|
""")
|
|
293
280
|
self.first = True
|
|
294
281
|
|
|
@@ -340,15 +327,17 @@ class Agent:
|
|
|
340
327
|
complete_prompt = f"- 输出{ot('!!!COMPLETE!!!')}" if need_complete and self.auto_complete else ""
|
|
341
328
|
|
|
342
329
|
addon_prompt = f"""
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
{
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
-
|
|
349
|
-
-
|
|
350
|
-
-
|
|
351
|
-
|
|
330
|
+
[系统提示开始]
|
|
331
|
+
请判断是否已经完成任务,如果已经完成:
|
|
332
|
+
- 直接输出完成原因,不需要再有新的操作,不要输出{ot("TOOL_CALL")}标签
|
|
333
|
+
{complete_prompt}
|
|
334
|
+
如果没有完成,请进行下一步操作:
|
|
335
|
+
- 仅包含一个操作
|
|
336
|
+
- 如果信息不明确,请请求用户补充
|
|
337
|
+
- 如果执行过程中连续失败5次,请使用ask_user询问用户操作
|
|
338
|
+
- 操作列表:
|
|
339
|
+
{action_handlers}
|
|
340
|
+
[系统提示结束]
|
|
352
341
|
|
|
353
342
|
请继续。
|
|
354
343
|
"""
|
|
@@ -490,7 +479,7 @@ class Agent:
|
|
|
490
479
|
return False, f"操作失败:检测到多个操作。一次只能执行一个操作。尝试执行的操作:{', '.join([handler.name() for handler in tool_list])}"
|
|
491
480
|
if len(tool_list) == 0:
|
|
492
481
|
return False, ""
|
|
493
|
-
if self.tool_call_count >= self.max_tool_call_count:
|
|
482
|
+
if self.max_tool_call_count > 0 and self.tool_call_count >= self.max_tool_call_count:
|
|
494
483
|
if user_confirm(f"工具调用次数超过限制,是否继续执行?", True):
|
|
495
484
|
self.reset_tool_call_count()
|
|
496
485
|
else:
|
|
@@ -522,34 +511,43 @@ class Agent:
|
|
|
522
511
|
2. 对于子Agent: 可能会生成总结(如果启用)
|
|
523
512
|
3. 使用spinner显示生成状态
|
|
524
513
|
"""
|
|
514
|
+
if self.use_methodology:
|
|
515
|
+
self._analysis_task()
|
|
516
|
+
if self.need_summary:
|
|
517
|
+
with yaspin(text="正在生成总结...", color="cyan") as spinner:
|
|
518
|
+
self.prompt = self.summary_prompt
|
|
519
|
+
with spinner.hidden():
|
|
520
|
+
ret = self.model.chat_until_success(self.prompt) # type: ignore
|
|
521
|
+
spinner.text = "总结生成完成"
|
|
522
|
+
spinner.ok("✅")
|
|
523
|
+
return ret
|
|
524
|
+
|
|
525
|
+
return "任务完成"
|
|
526
|
+
|
|
527
|
+
def _analysis_task(self):
|
|
525
528
|
with yaspin(text="正在分析任务...", color="cyan") as spinner:
|
|
526
529
|
try:
|
|
527
530
|
# 让模型判断是否需要生成方法论
|
|
528
531
|
analysis_prompt = f"""<task_analysis>
|
|
529
532
|
<request>
|
|
530
533
|
当前任务已结束,请分析该任务的解决方案:
|
|
531
|
-
|
|
532
534
|
1. 首先检查现有工具或方法论是否已经可以完成该任务,如果可以,直接说明即可,无需生成新内容
|
|
533
535
|
2. 如果现有工具/方法论不足,评估当前任务是否可以通过编写新工具来自动化解决
|
|
534
536
|
3. 如果可以通过工具解决,请设计并提供工具代码
|
|
535
537
|
4. 如果无法通过编写通用工具完成,评估当前的执行流程是否可以总结为通用方法论
|
|
536
538
|
5. 如果以上都不可行,给出详细理由
|
|
537
|
-
|
|
538
539
|
请根据分析结果采取相应行动:说明现有工具/方法论、创建新工具、生成新方法论或说明原因。
|
|
539
540
|
</request>
|
|
540
|
-
|
|
541
541
|
<evaluation_criteria>
|
|
542
542
|
现有资源评估:
|
|
543
543
|
1. 现有工具 - 检查系统中是否已有可以完成该任务的工具
|
|
544
544
|
2. 现有方法论 - 检查是否已有适用于该任务的方法论
|
|
545
545
|
3. 组合使用 - 评估现有工具和方法论组合使用是否可以解决问题
|
|
546
|
-
|
|
547
546
|
工具评估标准:
|
|
548
547
|
1. 通用性 - 该工具是否可以解决一类问题,而不仅仅是当前特定问题
|
|
549
548
|
2. 自动化 - 该工具是否可以减少人工干预,提高效率
|
|
550
549
|
3. 可靠性 - 该工具是否可以在不同场景下稳定工作
|
|
551
550
|
4. 简单性 - 该工具是否易于使用,参数设计是否合理
|
|
552
|
-
|
|
553
551
|
方法论评估标准:
|
|
554
552
|
1. 方法论应聚焦于通用且可重复的解决方案流程
|
|
555
553
|
2. 方法论应该具备足够的通用性,可应用于同类问题
|
|
@@ -557,7 +555,6 @@ class Agent:
|
|
|
557
555
|
4. 如果用户明确指出了某个解决步骤的优化方向,这应该被纳入方法论
|
|
558
556
|
5. 方法论要严格按照实际的执行流程来总结,不要遗漏或增加任何步骤
|
|
559
557
|
</evaluation_criteria>
|
|
560
|
-
|
|
561
558
|
<tool_requirements>
|
|
562
559
|
工具代码要求:
|
|
563
560
|
1. 工具类名应与工具名称保持一致
|
|
@@ -567,13 +564,11 @@ class Agent:
|
|
|
567
564
|
5. 工具描述应详细说明用途、适用场景和使用示例
|
|
568
565
|
6. 参数定义应遵循JSON Schema格式
|
|
569
566
|
7. 不要包含特定任务的细节,保持通用性
|
|
570
|
-
|
|
571
567
|
工具设计关键点:
|
|
572
568
|
1. **使用PrettyOutput打印执行过程**:强烈建议在工具中使用PrettyOutput显示执行过程,
|
|
573
569
|
这样用户可以了解工具在做什么,提升用户体验。示例:
|
|
574
570
|
```python
|
|
575
571
|
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
576
|
-
|
|
577
572
|
# 执行中打印信息
|
|
578
573
|
PrettyOutput.print("正在处理数据...", OutputType.INFO)
|
|
579
574
|
# 成功信息
|
|
@@ -583,12 +578,10 @@ class Agent:
|
|
|
583
578
|
# 错误信息
|
|
584
579
|
PrettyOutput.print("操作失败", OutputType.ERROR)
|
|
585
580
|
```
|
|
586
|
-
|
|
587
581
|
2. **结构化返回结果**:工具应该始终返回结构化的结果字典,包含以下字段:
|
|
588
582
|
- success: 布尔值,表示操作是否成功
|
|
589
583
|
- stdout: 字符串,包含工具的主要输出内容
|
|
590
584
|
- stderr: 字符串,包含错误信息(如果有)
|
|
591
|
-
|
|
592
585
|
3. **异常处理**:工具应该妥善处理可能发生的异常,并在失败时清理已创建的资源
|
|
593
586
|
```python
|
|
594
587
|
try:
|
|
@@ -608,7 +601,6 @@ class Agent:
|
|
|
608
601
|
}}
|
|
609
602
|
```
|
|
610
603
|
</tool_requirements>
|
|
611
|
-
|
|
612
604
|
<methodology_requirements>
|
|
613
605
|
方法论格式要求:
|
|
614
606
|
1. 问题重述: 简明扼要的问题归纳,不含特定细节
|
|
@@ -616,15 +608,12 @@ class Agent:
|
|
|
616
608
|
3. 注意事项: 执行中可能遇到的常见问题和注意点,尤其是用户指出的问题
|
|
617
609
|
4. 可选步骤: 对于有多种解决路径的问题,标注出可选步骤和适用场景
|
|
618
610
|
</methodology_requirements>
|
|
619
|
-
|
|
620
611
|
<output_requirements>
|
|
621
612
|
根据分析结果,输出以下三种情况之一:
|
|
622
|
-
|
|
623
613
|
1. 如果现有工具/方法论可以解决,直接输出说明:
|
|
624
614
|
已有工具/方法论可以解决该问题,无需创建新内容。
|
|
625
615
|
可用的工具/方法论:[列出工具名称或方法论名称]
|
|
626
616
|
使用方法:[简要说明如何使用]
|
|
627
|
-
|
|
628
617
|
2. 工具创建(如果需要创建新工具):
|
|
629
618
|
{ot("TOOL_CALL")}
|
|
630
619
|
want: 创建新工具来解决XXX问题
|
|
@@ -635,14 +624,12 @@ arguments:
|
|
|
635
624
|
# -*- coding: utf-8 -*-
|
|
636
625
|
from typing import Dict, Any
|
|
637
626
|
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
638
|
-
|
|
639
627
|
class 工具名称:
|
|
640
628
|
name = "工具名称"
|
|
641
629
|
description = "Tool for text transformation"
|
|
642
630
|
Tool description
|
|
643
631
|
适用场景:1. 格式化文本; 2. 处理标题; 3. 标准化输出
|
|
644
632
|
\"\"\"
|
|
645
|
-
|
|
646
633
|
parameters = {{
|
|
647
634
|
"type": "object",
|
|
648
635
|
"properties": {{
|
|
@@ -650,19 +637,15 @@ arguments:
|
|
|
650
637
|
}},
|
|
651
638
|
"required": []
|
|
652
639
|
}}
|
|
653
|
-
|
|
654
640
|
@staticmethod
|
|
655
641
|
def check() -> bool:
|
|
656
642
|
return True
|
|
657
|
-
|
|
658
643
|
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
659
644
|
try:
|
|
660
645
|
# 使用PrettyOutput显示执行过程
|
|
661
646
|
PrettyOutput.print("开始执行操作...", OutputType.INFO)
|
|
662
|
-
|
|
663
647
|
# 实现逻辑
|
|
664
648
|
# ...
|
|
665
|
-
|
|
666
649
|
PrettyOutput.print("操作已完成", OutputType.SUCCESS)
|
|
667
650
|
return {{
|
|
668
651
|
"success": True,
|
|
@@ -677,7 +660,6 @@ arguments:
|
|
|
677
660
|
"stderr": f"操作失败: {{str(e)}}"
|
|
678
661
|
}}
|
|
679
662
|
{ct("TOOL_CALL")}
|
|
680
|
-
|
|
681
663
|
3. 方法论创建(如果需要创建新方法论):
|
|
682
664
|
{ot("TOOL_CALL")}
|
|
683
665
|
want: 添加/更新xxxx的方法论
|
|
@@ -688,7 +670,6 @@ arguments:
|
|
|
688
670
|
content: |2
|
|
689
671
|
方法论内容
|
|
690
672
|
{ct("TOOL_CALL")}
|
|
691
|
-
|
|
692
673
|
如果以上三种情况都不适用,则直接输出原因分析,不要使用工具调用格式。
|
|
693
674
|
</output_requirements>
|
|
694
675
|
</task_analysis>"""
|
|
@@ -704,16 +685,6 @@ arguments:
|
|
|
704
685
|
except Exception as e:
|
|
705
686
|
spinner.text = "分析失败"
|
|
706
687
|
spinner.fail("❌")
|
|
707
|
-
if self.need_summary:
|
|
708
|
-
with yaspin(text="正在生成总结...", color="cyan") as spinner:
|
|
709
|
-
self.prompt = self.summary_prompt
|
|
710
|
-
with spinner.hidden():
|
|
711
|
-
ret = self.model.chat_until_success(self.prompt) # type: ignore
|
|
712
|
-
spinner.text = "总结生成完成"
|
|
713
|
-
spinner.ok("✅")
|
|
714
|
-
return ret
|
|
715
|
-
|
|
716
|
-
return "任务完成"
|
|
717
688
|
|
|
718
689
|
|
|
719
690
|
def run(self, user_input: str) -> Any:
|
|
@@ -736,7 +707,7 @@ arguments:
|
|
|
736
707
|
|
|
737
708
|
self.prompt = f"{user_input}"
|
|
738
709
|
|
|
739
|
-
if self.first:
|
|
710
|
+
if self.first and self.use_methodology:
|
|
740
711
|
|
|
741
712
|
# 先尝试上传方法轮
|
|
742
713
|
platform = self.model if hasattr(self.model, 'upload_files') else None
|
jarvis/jarvis_agent/jarvis.py
CHANGED
|
@@ -3,7 +3,7 @@ import argparse
|
|
|
3
3
|
import os
|
|
4
4
|
import sys
|
|
5
5
|
|
|
6
|
-
from typing import Dict #
|
|
6
|
+
from typing import Dict, List, Tuple # 增加必要的类型导入
|
|
7
7
|
|
|
8
8
|
from jarvis.jarvis_utils.config import get_data_dir
|
|
9
9
|
from prompt_toolkit import prompt
|
|
@@ -39,10 +39,10 @@ def _load_tasks() -> Dict[str, str]:
|
|
|
39
39
|
for name, desc in user_tasks.items():
|
|
40
40
|
if desc:
|
|
41
41
|
tasks[str(name)] = str(desc)
|
|
42
|
-
spinner.text = "预定义任务加载完成"
|
|
42
|
+
spinner.text = f"预定义任务加载完成{pre_command_path}"
|
|
43
43
|
spinner.ok("✅")
|
|
44
44
|
except (yaml.YAMLError, OSError):
|
|
45
|
-
spinner.text = "预定义任务加载失败"
|
|
45
|
+
spinner.text = f"预定义任务加载失败{pre_command_path}"
|
|
46
46
|
spinner.fail("❌")
|
|
47
47
|
|
|
48
48
|
# Check .jarvis/pre-command in current directory
|
|
@@ -58,10 +58,10 @@ def _load_tasks() -> Dict[str, str]:
|
|
|
58
58
|
for name, desc in local_tasks.items():
|
|
59
59
|
if desc:
|
|
60
60
|
tasks[str(name)] = str(desc)
|
|
61
|
-
spinner.text = "预定义任务加载完成"
|
|
61
|
+
spinner.text = f"预定义任务加载完成{pre_command_path}"
|
|
62
62
|
spinner.ok("✅")
|
|
63
63
|
except (yaml.YAMLError, OSError):
|
|
64
|
-
spinner.text = "预定义任务加载失败"
|
|
64
|
+
spinner.text = f"预定义任务加载失败{pre_command_path}"
|
|
65
65
|
spinner.fail("❌")
|
|
66
66
|
|
|
67
67
|
return tasks
|
|
@@ -90,6 +90,7 @@ def _select_task(tasks: Dict[str, str]) -> str:
|
|
|
90
90
|
return ""
|
|
91
91
|
if 1 <= choice <= len(task_names):
|
|
92
92
|
selected_task = tasks[task_names[choice - 1]]
|
|
93
|
+
PrettyOutput.print(f"将要执行任务:\n {selected_task}", OutputType.INFO)
|
|
93
94
|
# 询问是否需要补充信息
|
|
94
95
|
need_additional = user_confirm("需要为此任务添加补充信息吗?", default=False)
|
|
95
96
|
if need_additional:
|
|
@@ -105,11 +106,10 @@ def _select_task(tasks: Dict[str, str]) -> str:
|
|
|
105
106
|
PrettyOutput.print(f"选择任务失败: {str(val_err)}", OutputType.ERROR)
|
|
106
107
|
|
|
107
108
|
|
|
108
|
-
|
|
109
|
-
|
|
110
109
|
def main() -> None:
|
|
111
|
-
|
|
112
|
-
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
init_env("欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!")
|
|
113
113
|
parser = argparse.ArgumentParser(description='Jarvis AI assistant')
|
|
114
114
|
parser.add_argument('-p', '--platform', type=str, help='Platform to use')
|
|
115
115
|
parser.add_argument('-m', '--model', type=str, help='Model to use')
|
|
@@ -138,7 +138,7 @@ def main() -> None:
|
|
|
138
138
|
|
|
139
139
|
tasks = _load_tasks()
|
|
140
140
|
if tasks and (selected_task := _select_task(tasks)):
|
|
141
|
-
PrettyOutput.print(f"
|
|
141
|
+
PrettyOutput.print(f"开始执行任务: \n{selected_task}", OutputType.INFO)
|
|
142
142
|
agent.run(selected_task)
|
|
143
143
|
sys.exit(0)
|
|
144
144
|
|
jarvis/jarvis_agent/main.py
CHANGED
|
@@ -9,13 +9,13 @@ from jarvis.jarvis_utils.utils import init_env
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def load_config(config_path: str) -> dict:
|
|
12
|
-
"""
|
|
12
|
+
"""从YAML文件加载配置
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
config_path:
|
|
14
|
+
参数:
|
|
15
|
+
config_path: YAML配置文件的路径
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
dict:
|
|
17
|
+
返回:
|
|
18
|
+
dict: 配置字典
|
|
19
19
|
"""
|
|
20
20
|
if not os.path.exists(config_path):
|
|
21
21
|
PrettyOutput.print(f"配置文件 {config_path} 不存在,使用默认配置", OutputType.WARNING)
|
|
@@ -32,7 +32,7 @@ def load_config(config_path: str) -> dict:
|
|
|
32
32
|
def main():
|
|
33
33
|
"""Main entry point for Jarvis agent"""
|
|
34
34
|
# Initialize environment
|
|
35
|
-
init_env()
|
|
35
|
+
init_env("欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!")
|
|
36
36
|
|
|
37
37
|
# Set up argument parser
|
|
38
38
|
parser = argparse.ArgumentParser(description='Jarvis AI assistant')
|
|
@@ -31,7 +31,7 @@ from jarvis.jarvis_utils.git_utils import (
|
|
|
31
31
|
from jarvis.jarvis_utils.input import get_multiline_input
|
|
32
32
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
33
33
|
from jarvis.jarvis_utils.utils import init_env, user_confirm
|
|
34
|
-
|
|
34
|
+
from jarvis import __version__
|
|
35
35
|
|
|
36
36
|
class CodeAgent:
|
|
37
37
|
"""Jarvis系统的代码修改代理。
|
|
@@ -372,10 +372,14 @@ class CodeAgent:
|
|
|
372
372
|
final_ret += f"# 应用补丁:\n```diff\n{diff}\n```"
|
|
373
373
|
|
|
374
374
|
# 修改后的提示逻辑
|
|
375
|
-
addon_prompt = "
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
375
|
+
addon_prompt = """
|
|
376
|
+
[系统提示开始]
|
|
377
|
+
如果对应语言有静态检查工具,请使用静态检查工具检查修改的代码,如果本次修改引入了警告和错误,请根据警告和错误信息修复代码
|
|
378
|
+
在引入警告和错误都被修复的前提下,如果用户的需求未完成,请继续修改代码,如果已经完成,请终止,不要实现任何超出用户需求外的内容
|
|
379
|
+
如果有任何信息不明确,调用工具获取信息
|
|
380
|
+
每次响应必须且只能包含一个操作
|
|
381
|
+
[系统提示结束]
|
|
382
|
+
"""
|
|
379
383
|
|
|
380
384
|
agent.set_addon_prompt(addon_prompt)
|
|
381
385
|
|
|
@@ -403,7 +407,7 @@ class CodeAgent:
|
|
|
403
407
|
|
|
404
408
|
def main() -> None:
|
|
405
409
|
"""Jarvis主入口点。"""
|
|
406
|
-
init_env()
|
|
410
|
+
init_env("欢迎使用 Jarvis-CodeAgent,您的代码工程助手已准备就绪!")
|
|
407
411
|
|
|
408
412
|
parser = argparse.ArgumentParser(description='Jarvis Code Agent')
|
|
409
413
|
parser.add_argument('-p', '--platform', type=str,
|
|
@@ -661,7 +661,7 @@ def main():
|
|
|
661
661
|
"""CLI entry point"""
|
|
662
662
|
import argparse
|
|
663
663
|
|
|
664
|
-
init_env()
|
|
664
|
+
init_env("欢迎使用 Jarvis-CodeReview,您的代码审查助手已准备就绪!")
|
|
665
665
|
|
|
666
666
|
parser = argparse.ArgumentParser(description='Autonomous code review tool')
|
|
667
667
|
subparsers = parser.add_subparsers(dest='type')
|
jarvis/jarvis_dev/main.py
CHANGED
|
@@ -1257,7 +1257,7 @@ def create_dev_team() -> MultiAgent:
|
|
|
1257
1257
|
def main():
|
|
1258
1258
|
"""Main entry point for the development team simulation."""
|
|
1259
1259
|
|
|
1260
|
-
init_env()
|
|
1260
|
+
init_env("欢迎使用 Jarvis-Dev,您的开发团队已准备就绪!")
|
|
1261
1261
|
|
|
1262
1262
|
# Create the development team
|
|
1263
1263
|
dev_team = create_dev_team()
|
|
File without changes
|
|
@@ -233,7 +233,7 @@ def main():
|
|
|
233
233
|
"""主函数,用于命令行接口"""
|
|
234
234
|
import argparse
|
|
235
235
|
|
|
236
|
-
init_env()
|
|
236
|
+
init_env("欢迎使用 Jarvis-GitCommitAnalyzer,您的Git Commit分析助手已准备就绪!")
|
|
237
237
|
|
|
238
238
|
parser = argparse.ArgumentParser(description='Git Commit Analyzer')
|
|
239
239
|
group = parser.add_mutually_exclusive_group(required=True)
|
jarvis/jarvis_git_squash/main.py
CHANGED
|
@@ -46,7 +46,7 @@ class GitSquashTool:
|
|
|
46
46
|
PrettyOutput.print(f"压缩提交失败: {str(e)}", OutputType.WARNING)
|
|
47
47
|
|
|
48
48
|
def main():
|
|
49
|
-
init_env()
|
|
49
|
+
init_env("欢迎使用 Jarvis-GitSquash,您的Git压缩助手已准备就绪!")
|
|
50
50
|
parser = argparse.ArgumentParser(description='Git squash tool')
|
|
51
51
|
parser.add_argument('commit_hash', type=str, help='Base commit hash to squash from')
|
|
52
52
|
parser.add_argument('--lang', type=str, default='Chinese', help='Language for commit messages')
|
|
@@ -265,7 +265,7 @@ class GitCommitTool:
|
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
def main():
|
|
268
|
-
init_env()
|
|
268
|
+
init_env("欢迎使用 Jarvis-GitCommitTool,您的Git提交助手已准备就绪!")
|
|
269
269
|
parser = argparse.ArgumentParser(description='Git commit tool')
|
|
270
270
|
parser.add_argument('--lang', type=str, default='Chinese', help='Language for commit messages')
|
|
271
271
|
parser.add_argument('--root-dir', type=str, default='.', help='Root directory of the Git repository')
|
|
@@ -10,7 +10,7 @@ def main():
|
|
|
10
10
|
Returns:
|
|
11
11
|
最终处理结果
|
|
12
12
|
"""
|
|
13
|
-
init_env()
|
|
13
|
+
init_env("欢迎使用 Jarvis-MultiAgent,您的多智能体系统已准备就绪!")
|
|
14
14
|
import argparse
|
|
15
15
|
parser = argparse.ArgumentParser(description="多智能体系统启动器")
|
|
16
16
|
parser.add_argument("--config", "-c", required=True, help="YAML配置文件路径")
|
jarvis/jarvis_platform/base.py
CHANGED
|
@@ -58,7 +58,7 @@ class BasePlatform(ABC):
|
|
|
58
58
|
|
|
59
59
|
if input_token_count > get_max_input_token_count():
|
|
60
60
|
max_chunk_size = get_max_input_token_count() - 1024 # 留出一些余量
|
|
61
|
-
min_chunk_size =
|
|
61
|
+
min_chunk_size = get_max_input_token_count() - 2048
|
|
62
62
|
inputs = split_text_into_chunks(message, max_chunk_size, min_chunk_size)
|
|
63
63
|
with yaspin(text="正在提交长上下文...", color="cyan") as spinner:
|
|
64
64
|
prefix_prompt = f"""
|
|
@@ -66,10 +66,13 @@ class BasePlatform(ABC):
|
|
|
66
66
|
"""
|
|
67
67
|
while_true(lambda: while_success(lambda: self.chat(prefix_prompt), 5), 5)
|
|
68
68
|
submit_count = 0
|
|
69
|
+
length = 0
|
|
69
70
|
for input in inputs:
|
|
70
71
|
submit_count += 1
|
|
71
|
-
|
|
72
|
-
|
|
72
|
+
length += len(input)
|
|
73
|
+
spinner.text = f"正在提交第{submit_count}部分(共{len(inputs)}部分({length}/{len(message)}))"
|
|
74
|
+
list(while_true(lambda: while_success(lambda: self.chat(f"<part_content>{input}</part_content>请返回已收到"), 5), 5))
|
|
75
|
+
spinner.write(f"提交第{submit_count}部分完成,当前进度:{length}/{len(message)}")
|
|
73
76
|
spinner.text = "提交完成"
|
|
74
77
|
spinner.ok("✅")
|
|
75
78
|
response = while_true(lambda: while_success(lambda: self._chat("内容已经全部提供完毕,请继续"), 5), 5)
|
jarvis/jarvis_platform/openai.py
CHANGED
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
from typing import Dict, Generator, List, Tuple
|
|
3
3
|
import os
|
|
4
4
|
from openai import OpenAI
|
|
5
|
-
from rich.live import Live
|
|
6
|
-
from rich.text import Text
|
|
7
|
-
from rich.panel import Panel
|
|
8
|
-
from rich import box
|
|
9
5
|
from jarvis.jarvis_platform.base import BasePlatform
|
|
10
6
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
11
7
|
|
|
@@ -49,10 +45,27 @@ class OpenAIModel(BasePlatform):
|
|
|
49
45
|
self.system_message = ""
|
|
50
46
|
|
|
51
47
|
def upload_files(self, file_list: List[str]) -> bool:
|
|
48
|
+
"""
|
|
49
|
+
上传文件到OpenAI平台
|
|
50
|
+
|
|
51
|
+
参数:
|
|
52
|
+
file_list: 需要上传的文件路径列表
|
|
53
|
+
|
|
54
|
+
返回:
|
|
55
|
+
bool: 上传是否成功 (当前实现始终返回False)
|
|
56
|
+
"""
|
|
52
57
|
return False
|
|
53
58
|
|
|
54
59
|
def get_model_list(self) -> List[Tuple[str, str]]:
|
|
55
|
-
"""
|
|
60
|
+
"""
|
|
61
|
+
获取可用的OpenAI模型列表
|
|
62
|
+
|
|
63
|
+
返回:
|
|
64
|
+
List[Tuple[str, str]]: 模型ID和名称的元组列表
|
|
65
|
+
|
|
66
|
+
异常:
|
|
67
|
+
当API调用失败时会打印错误信息并返回空列表
|
|
68
|
+
"""
|
|
56
69
|
try:
|
|
57
70
|
models = self.client.models.list()
|
|
58
71
|
model_list = []
|
|
@@ -64,17 +77,41 @@ class OpenAIModel(BasePlatform):
|
|
|
64
77
|
return []
|
|
65
78
|
|
|
66
79
|
def set_model_name(self, model_name: str):
|
|
67
|
-
"""
|
|
80
|
+
"""
|
|
81
|
+
设置当前使用的模型名称
|
|
82
|
+
|
|
83
|
+
参数:
|
|
84
|
+
model_name: 要设置的模型名称
|
|
85
|
+
"""
|
|
68
86
|
|
|
69
87
|
self.model_name = model_name
|
|
70
88
|
|
|
71
89
|
def set_system_message(self, message: str):
|
|
72
|
-
"""
|
|
90
|
+
"""
|
|
91
|
+
设置系统消息(角色设定)
|
|
92
|
+
|
|
93
|
+
参数:
|
|
94
|
+
message: 系统消息内容
|
|
95
|
+
|
|
96
|
+
说明:
|
|
97
|
+
设置后会立即添加到消息历史中
|
|
98
|
+
"""
|
|
73
99
|
self.system_message = message
|
|
74
100
|
self.messages.append({"role": "system", "content": self.system_message})
|
|
75
101
|
|
|
76
102
|
def chat(self, message: str) -> Generator[str, None, None]:
|
|
77
|
-
"""
|
|
103
|
+
"""
|
|
104
|
+
执行对话并返回生成器
|
|
105
|
+
|
|
106
|
+
参数:
|
|
107
|
+
message: 用户输入的消息内容
|
|
108
|
+
|
|
109
|
+
返回:
|
|
110
|
+
Generator[str, None, None]: 生成器,逐块返回AI响应内容
|
|
111
|
+
|
|
112
|
+
异常:
|
|
113
|
+
当API调用失败时会抛出异常并打印错误信息
|
|
114
|
+
"""
|
|
78
115
|
try:
|
|
79
116
|
|
|
80
117
|
# Add user message to history
|
|
@@ -103,12 +140,25 @@ class OpenAIModel(BasePlatform):
|
|
|
103
140
|
raise Exception(f"Chat failed: {str(e)}")
|
|
104
141
|
|
|
105
142
|
def name(self) -> str:
|
|
106
|
-
"""
|
|
143
|
+
"""
|
|
144
|
+
获取当前使用的模型名称
|
|
145
|
+
|
|
146
|
+
返回:
|
|
147
|
+
str: 当前配置的模型名称
|
|
148
|
+
"""
|
|
107
149
|
return self.model_name
|
|
108
150
|
|
|
109
151
|
|
|
110
152
|
def delete_chat(self)->bool:
|
|
111
|
-
"""
|
|
153
|
+
"""
|
|
154
|
+
删除当前对话历史
|
|
155
|
+
|
|
156
|
+
返回:
|
|
157
|
+
bool: 操作是否成功
|
|
158
|
+
|
|
159
|
+
说明:
|
|
160
|
+
如果设置了系统消息,会保留系统消息
|
|
161
|
+
"""
|
|
112
162
|
if self.system_message:
|
|
113
163
|
self.messages = [{"role": "system", "content": self.system_message}]
|
|
114
164
|
else:
|
|
@@ -116,4 +166,10 @@ class OpenAIModel(BasePlatform):
|
|
|
116
166
|
return True
|
|
117
167
|
|
|
118
168
|
def support_web(self) -> bool:
|
|
169
|
+
"""
|
|
170
|
+
检查是否支持网页访问功能
|
|
171
|
+
|
|
172
|
+
返回:
|
|
173
|
+
bool: 当前是否支持网页访问 (OpenAI平台始终返回False)
|
|
174
|
+
"""
|
|
119
175
|
return False
|
|
@@ -294,7 +294,7 @@ class YuanbaoPlatform(BasePlatform):
|
|
|
294
294
|
with open(file_path, 'rb') as file:
|
|
295
295
|
file_content = file.read()
|
|
296
296
|
|
|
297
|
-
spinner.write(f"ℹ️
|
|
297
|
+
spinner.write(f"ℹ️ 上传文件大小: {len(file_content)}")
|
|
298
298
|
|
|
299
299
|
# Prepare headers for PUT request
|
|
300
300
|
host = f"{upload_info['bucketName']}.{upload_info.get('accelerateDomain', 'cos.accelerate.myqcloud.com')}"
|
|
@@ -606,7 +606,7 @@ def main():
|
|
|
606
606
|
"""Main function"""
|
|
607
607
|
import argparse
|
|
608
608
|
|
|
609
|
-
init_env()
|
|
609
|
+
init_env("欢迎使用 Jarvis-PlatformManager,您的平台管理助手已准备就绪!")
|
|
610
610
|
|
|
611
611
|
parser = argparse.ArgumentParser(description='Jarvis AI 平台')
|
|
612
612
|
subparsers = parser.add_subparsers(dest='command', help='可用子命令')
|