jarvis-ai-assistant 0.7.0__py3-none-any.whl → 0.7.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- jarvis/__init__.py +1 -1
- jarvis/jarvis_agent/__init__.py +243 -139
- jarvis/jarvis_agent/agent_manager.py +5 -10
- jarvis/jarvis_agent/builtin_input_handler.py +2 -6
- jarvis/jarvis_agent/config_editor.py +2 -7
- jarvis/jarvis_agent/event_bus.py +82 -12
- jarvis/jarvis_agent/file_context_handler.py +265 -15
- jarvis/jarvis_agent/file_methodology_manager.py +3 -4
- jarvis/jarvis_agent/jarvis.py +113 -98
- jarvis/jarvis_agent/language_extractors/__init__.py +57 -0
- jarvis/jarvis_agent/language_extractors/c_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/cpp_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/go_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/java_extractor.py +84 -0
- jarvis/jarvis_agent/language_extractors/javascript_extractor.py +79 -0
- jarvis/jarvis_agent/language_extractors/python_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/rust_extractor.py +21 -0
- jarvis/jarvis_agent/language_extractors/typescript_extractor.py +84 -0
- jarvis/jarvis_agent/language_support_info.py +486 -0
- jarvis/jarvis_agent/main.py +6 -12
- jarvis/jarvis_agent/memory_manager.py +7 -16
- jarvis/jarvis_agent/methodology_share_manager.py +10 -16
- jarvis/jarvis_agent/prompt_manager.py +1 -1
- jarvis/jarvis_agent/prompts.py +193 -171
- jarvis/jarvis_agent/protocols.py +8 -12
- jarvis/jarvis_agent/run_loop.py +77 -14
- jarvis/jarvis_agent/session_manager.py +2 -3
- jarvis/jarvis_agent/share_manager.py +12 -21
- jarvis/jarvis_agent/shell_input_handler.py +1 -2
- jarvis/jarvis_agent/task_analyzer.py +26 -4
- jarvis/jarvis_agent/task_manager.py +11 -27
- jarvis/jarvis_agent/tool_executor.py +2 -3
- jarvis/jarvis_agent/tool_share_manager.py +12 -24
- jarvis/jarvis_agent/web_server.py +55 -20
- jarvis/jarvis_c2rust/__init__.py +5 -5
- jarvis/jarvis_c2rust/cli.py +461 -499
- jarvis/jarvis_c2rust/collector.py +45 -53
- jarvis/jarvis_c2rust/constants.py +26 -0
- jarvis/jarvis_c2rust/library_replacer.py +264 -132
- jarvis/jarvis_c2rust/llm_module_agent.py +162 -190
- jarvis/jarvis_c2rust/loaders.py +207 -0
- jarvis/jarvis_c2rust/models.py +28 -0
- jarvis/jarvis_c2rust/optimizer.py +1592 -395
- jarvis/jarvis_c2rust/transpiler.py +1722 -1064
- jarvis/jarvis_c2rust/utils.py +385 -0
- jarvis/jarvis_code_agent/build_validation_config.py +2 -3
- jarvis/jarvis_code_agent/code_agent.py +394 -320
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +3 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +4 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +17 -2
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +3 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +36 -4
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +9 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +9 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +12 -1
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +22 -5
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +57 -32
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +62 -6
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +8 -9
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +290 -5
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +21 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +21 -3
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +72 -4
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +35 -3
- jarvis/jarvis_code_agent/code_analyzer/languages/java_language.py +212 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/javascript_language.py +254 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +52 -2
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +73 -1
- jarvis/jarvis_code_agent/code_analyzer/languages/typescript_language.py +280 -0
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +306 -152
- jarvis/jarvis_code_agent/code_analyzer/structured_code.py +556 -0
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +193 -18
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +18 -8
- jarvis/jarvis_code_agent/lint.py +258 -27
- jarvis/jarvis_code_agent/utils.py +0 -1
- jarvis/jarvis_code_analysis/code_review.py +19 -24
- jarvis/jarvis_data/config_schema.json +53 -26
- jarvis/jarvis_git_squash/main.py +4 -5
- jarvis/jarvis_git_utils/git_commiter.py +44 -49
- jarvis/jarvis_mcp/sse_mcp_client.py +20 -27
- jarvis/jarvis_mcp/stdio_mcp_client.py +11 -12
- jarvis/jarvis_mcp/streamable_mcp_client.py +15 -14
- jarvis/jarvis_memory_organizer/memory_organizer.py +55 -74
- jarvis/jarvis_methodology/main.py +32 -48
- jarvis/jarvis_multi_agent/__init__.py +79 -61
- jarvis/jarvis_multi_agent/main.py +3 -7
- jarvis/jarvis_platform/base.py +469 -199
- jarvis/jarvis_platform/human.py +7 -8
- jarvis/jarvis_platform/kimi.py +30 -36
- jarvis/jarvis_platform/openai.py +65 -27
- jarvis/jarvis_platform/registry.py +26 -10
- jarvis/jarvis_platform/tongyi.py +24 -25
- jarvis/jarvis_platform/yuanbao.py +31 -42
- jarvis/jarvis_platform_manager/main.py +66 -77
- jarvis/jarvis_platform_manager/service.py +8 -13
- jarvis/jarvis_rag/cli.py +49 -51
- jarvis/jarvis_rag/embedding_manager.py +13 -18
- jarvis/jarvis_rag/llm_interface.py +8 -9
- jarvis/jarvis_rag/query_rewriter.py +10 -21
- jarvis/jarvis_rag/rag_pipeline.py +24 -27
- jarvis/jarvis_rag/reranker.py +4 -5
- jarvis/jarvis_rag/retriever.py +28 -30
- jarvis/jarvis_sec/__init__.py +220 -3520
- jarvis/jarvis_sec/agents.py +143 -0
- jarvis/jarvis_sec/analysis.py +276 -0
- jarvis/jarvis_sec/cli.py +29 -6
- jarvis/jarvis_sec/clustering.py +1439 -0
- jarvis/jarvis_sec/file_manager.py +427 -0
- jarvis/jarvis_sec/parsers.py +73 -0
- jarvis/jarvis_sec/prompts.py +268 -0
- jarvis/jarvis_sec/report.py +83 -4
- jarvis/jarvis_sec/review.py +453 -0
- jarvis/jarvis_sec/utils.py +499 -0
- jarvis/jarvis_sec/verification.py +848 -0
- jarvis/jarvis_sec/workflow.py +7 -0
- jarvis/jarvis_smart_shell/main.py +38 -87
- jarvis/jarvis_stats/cli.py +1 -1
- jarvis/jarvis_stats/stats.py +7 -7
- jarvis/jarvis_stats/storage.py +15 -21
- jarvis/jarvis_tools/clear_memory.py +3 -20
- jarvis/jarvis_tools/cli/main.py +20 -23
- jarvis/jarvis_tools/edit_file.py +1066 -0
- jarvis/jarvis_tools/execute_script.py +42 -21
- jarvis/jarvis_tools/file_analyzer.py +6 -9
- jarvis/jarvis_tools/generate_new_tool.py +11 -20
- jarvis/jarvis_tools/lsp_client.py +1552 -0
- jarvis/jarvis_tools/methodology.py +2 -3
- jarvis/jarvis_tools/read_code.py +1525 -87
- jarvis/jarvis_tools/read_symbols.py +2 -3
- jarvis/jarvis_tools/read_webpage.py +7 -10
- jarvis/jarvis_tools/registry.py +370 -181
- jarvis/jarvis_tools/retrieve_memory.py +20 -19
- jarvis/jarvis_tools/rewrite_file.py +105 -0
- jarvis/jarvis_tools/save_memory.py +3 -15
- jarvis/jarvis_tools/search_web.py +3 -7
- jarvis/jarvis_tools/sub_agent.py +17 -6
- jarvis/jarvis_tools/sub_code_agent.py +14 -16
- jarvis/jarvis_tools/virtual_tty.py +54 -32
- jarvis/jarvis_utils/clipboard.py +7 -10
- jarvis/jarvis_utils/config.py +98 -63
- jarvis/jarvis_utils/embedding.py +5 -5
- jarvis/jarvis_utils/fzf.py +8 -8
- jarvis/jarvis_utils/git_utils.py +81 -67
- jarvis/jarvis_utils/input.py +24 -49
- jarvis/jarvis_utils/jsonnet_compat.py +465 -0
- jarvis/jarvis_utils/methodology.py +33 -35
- jarvis/jarvis_utils/utils.py +245 -202
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/METADATA +205 -70
- jarvis_ai_assistant-0.7.6.dist-info/RECORD +218 -0
- jarvis/jarvis_agent/edit_file_handler.py +0 -584
- jarvis/jarvis_agent/rewrite_file_handler.py +0 -141
- jarvis/jarvis_agent/task_planner.py +0 -496
- jarvis/jarvis_platform/ai8.py +0 -332
- jarvis/jarvis_tools/ask_user.py +0 -54
- jarvis_ai_assistant-0.7.0.dist-info/RECORD +0 -192
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.7.0.dist-info → jarvis_ai_assistant-0.7.6.dist-info}/top_level.txt +0 -0
jarvis/jarvis_agent/prompts.py
CHANGED
|
@@ -9,7 +9,11 @@ DEFAULT_SUMMARY_PROMPT = """<report>
|
|
|
9
9
|
2. 执行结果:成功/失败
|
|
10
10
|
3. 关键信息:执行过程中提取的重要信息
|
|
11
11
|
4. 重要发现:任何值得注意的发现
|
|
12
|
-
5.
|
|
12
|
+
5. 无效方案总结:如果当前是在修复问题,请总结尝试过但无效的方案,避免后续重复尝试
|
|
13
|
+
- 已尝试的方法及其失败原因
|
|
14
|
+
- 排除的错误假设
|
|
15
|
+
- 不可行的解决路径
|
|
16
|
+
6. 后续建议:如果有的话
|
|
13
17
|
</content>
|
|
14
18
|
|
|
15
19
|
<format>
|
|
@@ -20,44 +24,198 @@ DEFAULT_SUMMARY_PROMPT = """<report>
|
|
|
20
24
|
|
|
21
25
|
SUMMARY_REQUEST_PROMPT = """<summary_request>
|
|
22
26
|
<objective>
|
|
23
|
-
|
|
27
|
+
请对当前对话历史进行精准总结,核心目标是为后续对话提供“无关键信息缺失”的上下文支撑:既要提炼核心逻辑,又要完整保留影响后续决策/操作的关键细节,确保后续对话无需回溯原始历史即可顺畅推进。
|
|
24
28
|
</objective>
|
|
25
29
|
|
|
26
30
|
<guidelines>
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
3.
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
#### 一、必保保留的关键信息(按优先级排序,不可遗漏)
|
|
32
|
+
1. 核心目标与边界:用户最终要完成的任务(含量化指标,如“3天内实现接口”“QPS≥1000”)、明确排除的范围(如“暂不支持批量上传”);
|
|
33
|
+
2. 已确认的关键事实:技术栈(含版本,如“Python 3.9 + Django 4.2”)、环境配置(如“测试环境地址:http://test.example.com”)、数据/参数(如“数据库表名:user_info,分页大小:20条”);
|
|
34
|
+
3. 重要决策与共识:双方确认的方案(如“选用JWT做身份验证”)、否定的方案(如“排除Redis集群,用单机缓存”)、决策依据(如“因团队无K8s运维经验,选择Docker Compose”);
|
|
35
|
+
4. 技术细节(精准保留,不简化):
|
|
36
|
+
- 可直接复用的内容:完整命令(如“pip install requests==2.31.0”)、代码片段(关键逻辑,用`代码块`标注)、文件路径(如“/data/logs/app.log”)、接口地址/参数(如“POST /api/login,必填字段:phone/code”);
|
|
37
|
+
- 报错与调试信息:错误类型(如“IndexError”)、报错关键词(如“list index out of range”)、已尝试的有效/无效操作(如“修改索引为[-1]无效,更换httpx库报错消失”);
|
|
38
|
+
5. 任务进展与待办:
|
|
39
|
+
- 已完成步骤(如“已完成数据库表设计,已编写登录接口草稿”);
|
|
40
|
+
- 待解决问题(明确优先级,如“高:跨域问题未处理;中:异常捕获逻辑待补充”);
|
|
41
|
+
- 待确认/待补充信息(明确责任人与需求,如“用户需提供:测试数据库账号;助手需补充:接口文档示例”);
|
|
42
|
+
6. 用户偏好与约束:明确要求(如“代码需加注释”“输出JSON格式”)、限制条件(如“服务器内存4GB”“需兼容Windows 10”)、禁忌项(如“不可使用第三方ORM”)。
|
|
43
|
+
|
|
44
|
+
#### 二、可省略的冗余内容(无需保留)
|
|
45
|
+
- 寒暄与无关闲聊(如“您好”“谢谢”“今天天气不错”);
|
|
46
|
+
- 重复表述(用户多次强调的同一需求,仅保留1次核心表述);
|
|
47
|
+
- 临时试错/未落地的想法(如“我先试试这个思路”“可能用XX方案”,未确认的不保留);
|
|
48
|
+
- 与任务无关的细节(如“用户提及的其他项目经验”“无关的技术科普”)。
|
|
32
49
|
</guidelines>
|
|
33
50
|
|
|
34
51
|
<format>
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
-
|
|
38
|
-
|
|
52
|
+
1. 语言风格:简洁、客观、专业,使用编程领域规范表述(如“非阻塞IO”而非“不等待的输入输出”);
|
|
53
|
+
2. 结构组织:按“核心目标→已确认事实→决策与共识→技术细节→任务进展→待办事项→用户约束”的逻辑组织(替代“时间顺序”,更贴合后续对话需求);
|
|
54
|
+
3. 呈现形式:分点列出,关键技术内容用`代码块`/加粗标注,待办事项用“【优先级】+ 内容 + 责任人”明确(如“【高】补充跨域配置 - 助手”);
|
|
55
|
+
4. 长度限制:严格控制在500词以内,优先压缩冗余,不压缩必保信息(若必保信息较多,可适当放宽至600词)。
|
|
39
56
|
</format>
|
|
40
57
|
</summary_request>
|
|
41
58
|
"""
|
|
42
59
|
|
|
43
60
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
61
|
+
def get_task_analysis_prompt(
|
|
62
|
+
has_save_memory: bool = False,
|
|
63
|
+
has_generate_new_tool: bool = False
|
|
64
|
+
) -> str:
|
|
65
|
+
"""根据配置返回任务分析提示词
|
|
66
|
+
|
|
67
|
+
参数:
|
|
68
|
+
has_save_memory: 是否有 save_memory 工具(工具可用性)
|
|
69
|
+
has_generate_new_tool: 是否有 generate_new_tool 工具
|
|
70
|
+
"""
|
|
71
|
+
# 第一步:记忆保存部分
|
|
72
|
+
if not has_save_memory:
|
|
73
|
+
# 如果没有 save_memory 工具,说明无法保存记忆
|
|
74
|
+
memory_step = """第一步:记忆值得保存的信息
|
|
75
|
+
1. 识别任务中的关键信息和知识点
|
|
76
|
+
2. 评估是否有值得保存的项目长期记忆或全局长期记忆
|
|
77
|
+
3. 注意:当前环境不支持 save_memory 工具,无法保存记忆。请直接说明识别到的关键信息即可。"""
|
|
78
|
+
else:
|
|
79
|
+
# 有 save_memory 工具
|
|
80
|
+
memory_step = """第一步:记忆值得保存的信息
|
|
49
81
|
1. 识别任务中的关键信息和知识点
|
|
50
82
|
2. 评估是否有值得保存的项目长期记忆或全局长期记忆
|
|
51
|
-
3.
|
|
83
|
+
3. 如果有价值,使用 save_memory 工具保存有价值的信息:
|
|
52
84
|
- project_long_term: 保存与当前项目相关的长期信息(如项目配置、架构决策、开发规范等)
|
|
53
|
-
- global_long_term: 保存通用的信息、用户偏好、知识或方法(如技术知识、最佳实践、用户习惯等)
|
|
54
|
-
|
|
55
|
-
|
|
85
|
+
- global_long_term: 保存通用的信息、用户偏好、知识或方法(如技术知识、最佳实践、用户习惯等)"""
|
|
86
|
+
|
|
87
|
+
# 第二步:工具/方法论分析部分
|
|
88
|
+
if has_generate_new_tool:
|
|
89
|
+
solution_step = """第二步:分析任务解决方案
|
|
90
|
+
1. 检查现有工具或方法论是否已经可以完成该任务,如果可以,直接说明即可,无需生成新内容
|
|
91
|
+
2. 如果现有工具/方法论不足,评估当前任务是否可以通过编写新工具来自动化解决
|
|
92
|
+
3. 如果可以通过工具解决,请使用 generate_new_tool 工具创建新工具:
|
|
93
|
+
- 使用 generate_new_tool 工具,传入 tool_name 和 tool_code 参数
|
|
94
|
+
- tool_code 应包含完整的工具类定义,遵循工具代码要求
|
|
95
|
+
4. 如果无法通过编写通用工具完成,评估当前的执行流程是否可以总结为通用方法论
|
|
96
|
+
5. 如果以上都不可行,给出详细理由"""
|
|
97
|
+
else:
|
|
98
|
+
solution_step = """第二步:分析任务解决方案
|
|
56
99
|
1. 检查现有工具或方法论是否已经可以完成该任务,如果可以,直接说明即可,无需生成新内容
|
|
57
100
|
2. 如果现有工具/方法论不足,评估当前任务是否可以通过编写新工具来自动化解决
|
|
58
|
-
3.
|
|
101
|
+
3. 如果可以通过工具解决,请设计并提供工具代码(注意:当前环境不支持 generate_new_tool 工具,需要手动创建工具文件)
|
|
59
102
|
4. 如果无法通过编写通用工具完成,评估当前的执行流程是否可以总结为通用方法论
|
|
60
|
-
5. 如果以上都不可行,给出详细理由
|
|
103
|
+
5. 如果以上都不可行,给出详细理由"""
|
|
104
|
+
|
|
105
|
+
# 输出要求部分
|
|
106
|
+
if has_generate_new_tool:
|
|
107
|
+
output_requirements = f"""<output_requirements>
|
|
108
|
+
根据分析结果,输出以下三种情况之一:
|
|
109
|
+
1. 如果现有工具/方法论可以解决,直接输出说明:
|
|
110
|
+
已有工具/方法论可以解决该问题,无需创建新内容。
|
|
111
|
+
可用的工具/方法论:[列出工具名称或方法论名称]
|
|
112
|
+
使用方法:[简要说明如何使用]
|
|
113
|
+
2. 工具创建(如果需要创建新工具):
|
|
114
|
+
{ot("TOOL_CALL")}
|
|
115
|
+
{{
|
|
116
|
+
"want": "创建新工具来解决XXX问题",
|
|
117
|
+
"name": "generate_new_tool",
|
|
118
|
+
"arguments": {{
|
|
119
|
+
"tool_name": "工具名称",
|
|
120
|
+
"tool_code": `# -*- coding: utf-8 -*-
|
|
121
|
+
from typing import Dict, Any
|
|
122
|
+
|
|
123
|
+
class 工具名称:
|
|
124
|
+
name = "工具名称"
|
|
125
|
+
description = "Tool description"
|
|
126
|
+
parameters = {{
|
|
127
|
+
"type": "object",
|
|
128
|
+
"properties": {{
|
|
129
|
+
# 参数定义
|
|
130
|
+
}},
|
|
131
|
+
"required": []
|
|
132
|
+
}}
|
|
133
|
+
@staticmethod
|
|
134
|
+
def check() -> bool:
|
|
135
|
+
return True
|
|
136
|
+
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
137
|
+
try:
|
|
138
|
+
# 使用print显示执行过程
|
|
139
|
+
print("ℹ️ 开始执行操作...")
|
|
140
|
+
# 实现逻辑
|
|
141
|
+
# ...
|
|
142
|
+
print("✅ 操作已完成")
|
|
143
|
+
return {{
|
|
144
|
+
"success": True,
|
|
145
|
+
"stdout": "结果输出",
|
|
146
|
+
"stderr": ""
|
|
147
|
+
}}
|
|
148
|
+
except Exception as e:
|
|
149
|
+
print(f"❌ 操作失败: {{str(e)}}")
|
|
150
|
+
return {{
|
|
151
|
+
"success": False,
|
|
152
|
+
"stdout": "",
|
|
153
|
+
"stderr": f"操作失败: {{str(e)}}"
|
|
154
|
+
}}`
|
|
155
|
+
}}
|
|
156
|
+
}}
|
|
157
|
+
{ct("TOOL_CALL")}
|
|
158
|
+
|
|
159
|
+
注意:tool_code 参数推荐使用 ||| 或 ``` 分隔符包裹多行代码,直接换行无需转义,支持保留缩进。
|
|
160
|
+
3. 方法论创建(如果需要创建新方法论):
|
|
161
|
+
{ot("TOOL_CALL")}
|
|
162
|
+
{{
|
|
163
|
+
"want": "添加/更新xxxx的方法论",
|
|
164
|
+
"name": "methodology",
|
|
165
|
+
"arguments": {{
|
|
166
|
+
"operation": "add/update",
|
|
167
|
+
"problem_type": "方法论类型,不要过于细节,也不要过于泛化",
|
|
168
|
+
"content": |||
|
|
169
|
+
方法论内容
|
|
170
|
+
可以包含多行内容
|
|
171
|
+
推荐使用 ||| 或 ``` 分隔符包裹多行字符串,直接换行无需转义,支持保留缩进
|
|
172
|
+
包含"双引号"和'单引号'都无需转义
|
|
173
|
+
|||
|
|
174
|
+
}}
|
|
175
|
+
}}
|
|
176
|
+
{ct("TOOL_CALL")}
|
|
177
|
+
|
|
178
|
+
注意:如果 content 参数包含多行内容,推荐使用 ||| 或 ``` 分隔符包裹,直接换行无需转义,支持保留缩进。
|
|
179
|
+
如果以上三种情况都不适用,则直接输出原因分析,不要使用工具调用格式。
|
|
180
|
+
</output_requirements>"""
|
|
181
|
+
else:
|
|
182
|
+
output_requirements = f"""<output_requirements>
|
|
183
|
+
根据分析结果,输出以下三种情况之一:
|
|
184
|
+
1. 如果现有工具/方法论可以解决,直接输出说明:
|
|
185
|
+
已有工具/方法论可以解决该问题,无需创建新内容。
|
|
186
|
+
可用的工具/方法论:[列出工具名称或方法论名称]
|
|
187
|
+
使用方法:[简要说明如何使用]
|
|
188
|
+
2. 工具创建(如果需要创建新工具):
|
|
189
|
+
注意:当前环境不支持 generate_new_tool 工具。如果需要创建新工具,请提供完整的工具代码和说明,用户需要手动创建工具文件。
|
|
190
|
+
3. 方法论创建(如果需要创建新方法论):
|
|
191
|
+
{ot("TOOL_CALL")}
|
|
192
|
+
{{
|
|
193
|
+
"want": "添加/更新xxxx的方法论",
|
|
194
|
+
"name": "methodology",
|
|
195
|
+
"arguments": {{
|
|
196
|
+
"operation": "add/update",
|
|
197
|
+
"problem_type": "方法论类型,不要过于细节,也不要过于泛化",
|
|
198
|
+
"content": |||
|
|
199
|
+
方法论内容
|
|
200
|
+
可以包含多行内容
|
|
201
|
+
推荐使用 ||| 或 ``` 分隔符包裹多行字符串,直接换行无需转义,支持保留缩进
|
|
202
|
+
包含"双引号"和'单引号'都无需转义
|
|
203
|
+
|||
|
|
204
|
+
}}
|
|
205
|
+
}}
|
|
206
|
+
{ct("TOOL_CALL")}
|
|
207
|
+
|
|
208
|
+
注意:如果 content 参数包含多行内容,推荐使用 ||| 或 ``` 分隔符包裹,直接换行无需转义,支持保留缩进。
|
|
209
|
+
如果以上三种情况都不适用,则直接输出原因分析,不要使用工具调用格式。
|
|
210
|
+
</output_requirements>"""
|
|
211
|
+
|
|
212
|
+
return f"""<task_analysis>
|
|
213
|
+
<request>
|
|
214
|
+
当前任务已结束,请按以下步骤分析该任务:
|
|
215
|
+
|
|
216
|
+
{memory_step}
|
|
217
|
+
|
|
218
|
+
{solution_step}
|
|
61
219
|
|
|
62
220
|
请根据分析结果采取相应行动。
|
|
63
221
|
|
|
@@ -67,159 +225,23 @@ TASK_ANALYSIS_PROMPT = f"""<task_analysis>
|
|
|
67
225
|
- 不要在一次响应中同时调用多个工具(如同时保存记忆和创建工具/方法论)
|
|
68
226
|
</request>
|
|
69
227
|
<evaluation_criteria>
|
|
70
|
-
现有资源评估:
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
3. 组合使用 - 评估现有工具和方法论组合使用是否可以解决问题
|
|
74
|
-
工具评估标准:
|
|
75
|
-
1. 通用性 - 该工具是否可以解决一类问题,而不仅仅是当前特定问题
|
|
76
|
-
2. 自动化 - 该工具是否可以减少人工干预,提高效率
|
|
77
|
-
3. 可靠性 - 该工具是否可以在不同场景下稳定工作
|
|
78
|
-
4. 简单性 - 该工具是否易于使用,参数设计是否合理
|
|
79
|
-
方法论评估标准:
|
|
80
|
-
1. 方法论应聚焦于通用且可重复的解决方案流程
|
|
81
|
-
2. 方法论应该具备足够的通用性,可应用于同类问题
|
|
82
|
-
3. 特别注意用户在执行过程中提供的修正、反馈和改进建议
|
|
83
|
-
4. 如果用户明确指出了某个解决步骤的优化方向,这应该被纳入方法论
|
|
84
|
-
5. 方法论应面向未来复用,总结“下次遇到同类问题应该如何处理”的通用流程与检查清单,避免局限于本次执行细节
|
|
228
|
+
现有资源评估: 检查现有工具/方法论/组合使用是否可解决问题
|
|
229
|
+
工具评估: 通用性、自动化、可靠性、简单性
|
|
230
|
+
方法论评估: 聚焦通用可重复流程,纳入用户反馈,面向未来复用
|
|
85
231
|
</evaluation_criteria>
|
|
86
232
|
<tool_requirements>
|
|
87
233
|
工具代码要求:
|
|
88
|
-
1.
|
|
89
|
-
2.
|
|
90
|
-
3.
|
|
91
|
-
4.
|
|
92
|
-
5. 工具描述应详细说明用途、适用场景和使用示例
|
|
93
|
-
6. 参数定义应遵循JSON Schema格式
|
|
94
|
-
7. 不要包含特定任务的细节,保持通用性
|
|
95
|
-
工具设计关键点:
|
|
96
|
-
1. **使用PrettyOutput打印执行过程**:强烈建议在工具中使用PrettyOutput显示执行过程,
|
|
97
|
-
这样用户可以了解工具在做什么,提升用户体验。示例:
|
|
98
|
-
```python
|
|
99
|
-
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
100
|
-
# 执行中打印信息
|
|
101
|
-
PrettyOutput.print("正在处理数据...", OutputType.INFO)
|
|
102
|
-
# 成功信息
|
|
103
|
-
PrettyOutput.print("操作成功完成", OutputType.SUCCESS)
|
|
104
|
-
# 警告信息
|
|
105
|
-
PrettyOutput.print("发现潜在问题", OutputType.WARNING)
|
|
106
|
-
# 错误信息
|
|
107
|
-
PrettyOutput.print("操作失败", OutputType.ERROR)
|
|
108
|
-
```
|
|
109
|
-
2. **结构化返回结果**:工具应该始终返回结构化的结果字典,包含以下字段:
|
|
110
|
-
- success: 布尔值,表示操作是否成功
|
|
111
|
-
- stdout: 字符串,包含工具的主要输出内容
|
|
112
|
-
- stderr: 字符串,包含错误信息(如果有)
|
|
113
|
-
3. **异常处理**:工具应该妥善处理可能发生的异常,并在失败时清理已创建的资源
|
|
114
|
-
```python
|
|
115
|
-
try:
|
|
116
|
-
# 执行逻辑
|
|
117
|
-
return {{
|
|
118
|
-
"success": True,
|
|
119
|
-
"stdout": "成功结果",
|
|
120
|
-
"stderr": ""
|
|
121
|
-
}}
|
|
122
|
-
except Exception as e:
|
|
123
|
-
PrettyOutput.print(f"操作失败: {{str(e)}}", OutputType.ERROR)
|
|
124
|
-
# 清理资源(如果有创建)
|
|
125
|
-
return {{
|
|
126
|
-
"success": False,
|
|
127
|
-
"stdout": "",
|
|
128
|
-
"stderr": f"操作失败: {{str(e)}}"
|
|
129
|
-
}}
|
|
130
|
-
```
|
|
131
|
-
4. **在工具中调用大模型**:如果工具需要调用大模型来完成子任务(例如,生成代码、分析文本等),为了避免干扰主对话流程,建议创建一个独立的大模型实例。
|
|
132
|
-
```python
|
|
133
|
-
# 通过 agent 实例获取模型配置
|
|
134
|
-
agent = args.get("agent")
|
|
135
|
-
if not agent:
|
|
136
|
-
return {{"success": False, "stderr": "Agent not found."}}
|
|
137
|
-
|
|
138
|
-
current_model = agent.model
|
|
139
|
-
platform_name = current_model.platform_name()
|
|
140
|
-
model_name = current_model.name()
|
|
141
|
-
|
|
142
|
-
# 创建独立的模型实例
|
|
143
|
-
from jarvis.jarvis_platform.registry import PlatformRegistry
|
|
144
|
-
llm = PlatformRegistry().create_platform(platform_name)
|
|
145
|
-
if not llm:
|
|
146
|
-
return {{"success": False, "stderr": f"Platform {{platform_name}} not found."}}
|
|
147
|
-
|
|
148
|
-
llm.set_model_name(model_name)
|
|
149
|
-
llm.set_suppress_output(True) # 工具内的调用通常不需要流式输出
|
|
150
|
-
|
|
151
|
-
# 使用新实例调用大模型
|
|
152
|
-
PrettyOutput.print("正在执行子任务...", OutputType.INFO)
|
|
153
|
-
response = llm.chat_until_success("你的提示词")
|
|
154
|
-
PrettyOutput.print("子任务完成", OutputType.SUCCESS)
|
|
155
|
-
```
|
|
234
|
+
1. 工具类名与工具名称一致,包含name、description、parameters属性,实现execute方法
|
|
235
|
+
2. 参数定义遵循JSON Schema,工具调用使用Jsonnet格式(支持 ||| 或 ``` 分隔符多行字符串、尾随逗号)
|
|
236
|
+
3. 使用print显示执行过程,返回{{success, stdout, stderr}}结构化结果
|
|
237
|
+
4. 妥善处理异常,失败时清理资源。如需调用大模型,创建独立实例避免干扰主流程
|
|
156
238
|
</tool_requirements>
|
|
157
239
|
<methodology_requirements>
|
|
158
|
-
|
|
159
|
-
1. 问题重述: 简明扼要的问题归纳,不含特定细节
|
|
160
|
-
2. 可复用解决流程: 面向“下次遇到同类问题”的步骤化方案(列出每步可用的工具),避免与本次特定上下文绑定
|
|
161
|
-
3. 注意事项: 执行中可能遇到的常见问题和注意点,尤其是用户指出的问题
|
|
162
|
-
4. 可选步骤: 对于有多种解决路径的问题,标注出可选步骤和适用场景
|
|
240
|
+
方法论格式: 问题重述、可复用解决流程(步骤化+工具)、注意事项、可选步骤
|
|
163
241
|
</methodology_requirements>
|
|
164
|
-
|
|
165
|
-
根据分析结果,输出以下三种情况之一:
|
|
166
|
-
1. 如果现有工具/方法论可以解决,直接输出说明:
|
|
167
|
-
已有工具/方法论可以解决该问题,无需创建新内容。
|
|
168
|
-
可用的工具/方法论:[列出工具名称或方法论名称]
|
|
169
|
-
使用方法:[简要说明如何使用]
|
|
170
|
-
2. 工具创建(如果需要创建新工具):
|
|
171
|
-
{ot("TOOL_CALL")}
|
|
172
|
-
want: 创建新工具来解决XXX问题
|
|
173
|
-
name: generate_new_tool
|
|
174
|
-
arguments:
|
|
175
|
-
tool_name: 工具名称
|
|
176
|
-
tool_code: |2
|
|
177
|
-
# -*- coding: utf-8 -*-
|
|
178
|
-
from typing import Dict, Any
|
|
179
|
-
from jarvis.jarvis_utils.output import PrettyOutput, OutputType
|
|
180
|
-
class 工具名称:
|
|
181
|
-
name = "工具名称"
|
|
182
|
-
description = "Tool description"
|
|
183
|
-
parameters = {{
|
|
184
|
-
"type": "object",
|
|
185
|
-
"properties": {{
|
|
186
|
-
# 参数定义
|
|
187
|
-
}},
|
|
188
|
-
"required": []
|
|
189
|
-
}}
|
|
190
|
-
@staticmethod
|
|
191
|
-
def check() -> bool:
|
|
192
|
-
return True
|
|
193
|
-
def execute(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
|
194
|
-
try:
|
|
195
|
-
# 使用PrettyOutput显示执行过程
|
|
196
|
-
PrettyOutput.print("开始执行操作...", OutputType.INFO)
|
|
197
|
-
# 实现逻辑
|
|
198
|
-
# ...
|
|
199
|
-
PrettyOutput.print("操作已完成", OutputType.SUCCESS)
|
|
200
|
-
return {{
|
|
201
|
-
"success": True,
|
|
202
|
-
"stdout": "结果输出",
|
|
203
|
-
"stderr": ""
|
|
204
|
-
}}
|
|
205
|
-
except Exception as e:
|
|
206
|
-
PrettyOutput.print(f"操作失败: {{str(e)}}", OutputType.ERROR)
|
|
207
|
-
return {{
|
|
208
|
-
"success": False,
|
|
209
|
-
"stdout": "",
|
|
210
|
-
"stderr": f"操作失败: {{str(e)}}"
|
|
211
|
-
}}
|
|
212
|
-
{ct("TOOL_CALL")}
|
|
213
|
-
3. 方法论创建(如果需要创建新方法论):
|
|
214
|
-
{ot("TOOL_CALL")}
|
|
215
|
-
want: 添加/更新xxxx的方法论
|
|
216
|
-
name: methodology
|
|
217
|
-
arguments:
|
|
218
|
-
operation: add/update
|
|
219
|
-
problem_type: 方法论类型,不要过于细节,也不要过于泛化
|
|
220
|
-
content: |2
|
|
221
|
-
方法论内容
|
|
222
|
-
{ct("TOOL_CALL")}
|
|
223
|
-
如果以上三种情况都不适用,则直接输出原因分析,不要使用工具调用格式。
|
|
224
|
-
</output_requirements>
|
|
242
|
+
{output_requirements}
|
|
225
243
|
</task_analysis>"""
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
# 为了向后兼容,保留原来的常量(使用默认参数,假设有 save_memory 工具)
|
|
247
|
+
TASK_ANALYSIS_PROMPT = get_task_analysis_prompt(has_save_memory=True)
|
jarvis/jarvis_agent/protocols.py
CHANGED
|
@@ -1,33 +1,29 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
1
|
from typing import Any, Protocol, Tuple, runtime_checkable
|
|
3
2
|
|
|
4
3
|
|
|
5
4
|
@runtime_checkable
|
|
6
5
|
class OutputHandlerProtocol(Protocol):
|
|
7
6
|
"""
|
|
8
|
-
|
|
9
|
-
processing the model's response, typically to execute a tool.
|
|
7
|
+
定义输出处理器的接口,该处理器负责处理模型的响应,通常用于执行工具。
|
|
10
8
|
"""
|
|
11
9
|
|
|
12
10
|
def name(self) -> str:
|
|
13
|
-
"""
|
|
11
|
+
"""返回处理器的名称。"""
|
|
14
12
|
...
|
|
15
13
|
|
|
16
14
|
def can_handle(self, response: str) -> bool:
|
|
17
|
-
"""
|
|
15
|
+
"""判断此处理器能否处理给定的响应。"""
|
|
18
16
|
...
|
|
19
17
|
|
|
20
18
|
def prompt(self) -> str:
|
|
21
|
-
"""
|
|
19
|
+
"""返回描述处理器功能的提示片段。"""
|
|
22
20
|
...
|
|
23
21
|
|
|
24
22
|
def handle(self, response: str, agent: Any) -> Tuple[bool, Any]:
|
|
25
23
|
"""
|
|
26
|
-
|
|
24
|
+
处理响应,执行相关逻辑。
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
26
|
+
返回:
|
|
27
|
+
一个元组,包含一个布尔值(是否返回)和结果。
|
|
30
28
|
"""
|
|
31
|
-
...
|
|
32
|
-
|
|
33
|
-
__all__ = ["OutputHandlerProtocol"]
|
|
29
|
+
...
|
jarvis/jarvis_agent/run_loop.py
CHANGED
|
@@ -11,10 +11,9 @@ import os
|
|
|
11
11
|
from enum import Enum
|
|
12
12
|
from typing import Any, TYPE_CHECKING
|
|
13
13
|
|
|
14
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
15
14
|
from jarvis.jarvis_agent.events import BEFORE_TOOL_CALL, AFTER_TOOL_CALL
|
|
16
15
|
from jarvis.jarvis_agent.utils import join_prompts, is_auto_complete, normalize_next_action
|
|
17
|
-
from jarvis.jarvis_utils.config import
|
|
16
|
+
from jarvis.jarvis_utils.config import get_max_input_token_count, get_conversation_turn_threshold
|
|
18
17
|
|
|
19
18
|
if TYPE_CHECKING:
|
|
20
19
|
# 仅用于类型标注,避免运行时循环依赖
|
|
@@ -26,12 +25,10 @@ class AgentRunLoop:
|
|
|
26
25
|
self.agent = agent
|
|
27
26
|
self.conversation_rounds = 0
|
|
28
27
|
self.tool_reminder_rounds = int(os.environ.get("JARVIS_TOOL_REMINDER_ROUNDS", 20))
|
|
29
|
-
#
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
else get_auto_summary_rounds()
|
|
34
|
-
)
|
|
28
|
+
# 基于剩余token数量的自动总结阈值:当剩余token低于输入窗口的20%时触发
|
|
29
|
+
max_input_tokens = get_max_input_token_count(self.agent.model_group)
|
|
30
|
+
self.summary_remaining_token_threshold = int(max_input_tokens * 0.2)
|
|
31
|
+
self.conversation_turn_threshold = get_conversation_turn_threshold()
|
|
35
32
|
|
|
36
33
|
def run(self) -> Any:
|
|
37
34
|
"""主运行循环(委派到传入的 agent 实例的方法与属性)"""
|
|
@@ -44,15 +41,20 @@ class AgentRunLoop:
|
|
|
44
41
|
self.agent.session.addon_prompt = join_prompts(
|
|
45
42
|
[self.agent.session.addon_prompt, self.agent.get_tool_usage_prompt()]
|
|
46
43
|
)
|
|
47
|
-
#
|
|
48
|
-
|
|
44
|
+
# 基于剩余token数量或对话轮次的自动总结判断
|
|
45
|
+
remaining_tokens = self.agent.model.get_remaining_token_count()
|
|
46
|
+
should_summarize = (
|
|
47
|
+
remaining_tokens <= self.summary_remaining_token_threshold or
|
|
48
|
+
self.conversation_rounds > self.conversation_turn_threshold
|
|
49
|
+
)
|
|
50
|
+
if should_summarize:
|
|
49
51
|
summary_text = self.agent._summarize_and_clear_history()
|
|
50
52
|
if summary_text:
|
|
51
53
|
# 将摘要作为下一轮的附加提示加入,从而维持上下文连续性
|
|
52
54
|
self.agent.session.addon_prompt = join_prompts(
|
|
53
55
|
[self.agent.session.addon_prompt, summary_text]
|
|
54
56
|
)
|
|
55
|
-
#
|
|
57
|
+
# 重置轮次计数(用于工具提醒)与对话长度计数器(用于摘要触发),开始新一轮周期
|
|
56
58
|
self.conversation_rounds = 0
|
|
57
59
|
self.agent.session.conversation_length = 0
|
|
58
60
|
|
|
@@ -75,6 +77,25 @@ class AgentRunLoop:
|
|
|
75
77
|
ag.session.prompt = ""
|
|
76
78
|
run_input_handlers = False
|
|
77
79
|
|
|
80
|
+
# 检查是否包含 <!!!SUMMARY!!!> 标记,触发总结并清空历史
|
|
81
|
+
if "<!!!SUMMARY!!!>" in current_response:
|
|
82
|
+
print("ℹ️ 检测到 <!!!SUMMARY!!!> 标记,正在触发总结并清空历史...")
|
|
83
|
+
# 移除标记,避免在后续处理中出现
|
|
84
|
+
current_response = current_response.replace("<!!!SUMMARY!!!>", "").strip()
|
|
85
|
+
# 触发总结并清空历史
|
|
86
|
+
summary_text = ag._summarize_and_clear_history()
|
|
87
|
+
if summary_text:
|
|
88
|
+
# 将摘要作为下一轮的附加提示加入,从而维持上下文连续性
|
|
89
|
+
ag.session.addon_prompt = join_prompts(
|
|
90
|
+
[ag.session.addon_prompt, summary_text]
|
|
91
|
+
)
|
|
92
|
+
# 重置轮次计数(用于工具提醒)与对话长度计数器(用于摘要触发),开始新一轮周期
|
|
93
|
+
self.conversation_rounds = 0
|
|
94
|
+
ag.session.conversation_length = 0
|
|
95
|
+
# 如果响应中还有其他内容,继续处理;否则继续下一轮
|
|
96
|
+
if not current_response:
|
|
97
|
+
continue
|
|
98
|
+
|
|
78
99
|
# 处理中断
|
|
79
100
|
interrupt_result = ag._handle_run_interrupt(current_response)
|
|
80
101
|
if (
|
|
@@ -88,7 +109,7 @@ class AgentRunLoop:
|
|
|
88
109
|
return interrupt_result
|
|
89
110
|
|
|
90
111
|
# 处理工具调用
|
|
91
|
-
#
|
|
112
|
+
# 非关键流程:广播工具调用前事件(用于日志、监控等)
|
|
92
113
|
try:
|
|
93
114
|
ag.event_bus.emit(
|
|
94
115
|
BEFORE_TOOL_CALL,
|
|
@@ -101,13 +122,32 @@ class AgentRunLoop:
|
|
|
101
122
|
|
|
102
123
|
# 如果工具要求立即返回结果(例如 SEND_MESSAGE 需要将字典返回给上层),直接返回该结果
|
|
103
124
|
if need_return:
|
|
125
|
+
ag._no_tool_call_count = 0
|
|
104
126
|
return tool_prompt
|
|
105
127
|
|
|
106
128
|
# 将上一个提示和工具提示安全地拼接起来(仅当工具结果为字符串时)
|
|
107
129
|
safe_tool_prompt = tool_prompt if isinstance(tool_prompt, str) else ""
|
|
130
|
+
|
|
108
131
|
ag.session.prompt = join_prompts([ag.session.prompt, safe_tool_prompt])
|
|
109
132
|
|
|
110
|
-
#
|
|
133
|
+
# 关键流程:直接调用 after_tool_call 回调函数
|
|
134
|
+
try:
|
|
135
|
+
# 获取所有订阅了 AFTER_TOOL_CALL 事件的回调
|
|
136
|
+
listeners = ag.event_bus._listeners.get(AFTER_TOOL_CALL, [])
|
|
137
|
+
for callback in listeners:
|
|
138
|
+
try:
|
|
139
|
+
callback(
|
|
140
|
+
agent=ag,
|
|
141
|
+
current_response=current_response,
|
|
142
|
+
need_return=need_return,
|
|
143
|
+
tool_prompt=tool_prompt,
|
|
144
|
+
)
|
|
145
|
+
except Exception:
|
|
146
|
+
pass
|
|
147
|
+
except Exception:
|
|
148
|
+
pass
|
|
149
|
+
|
|
150
|
+
# 非关键流程:广播工具调用后的事件(用于日志、监控等)
|
|
111
151
|
try:
|
|
112
152
|
ag.event_bus.emit(
|
|
113
153
|
AFTER_TOOL_CALL,
|
|
@@ -121,10 +161,12 @@ class AgentRunLoop:
|
|
|
121
161
|
|
|
122
162
|
# 检查是否需要继续
|
|
123
163
|
if ag.session.prompt or ag.session.addon_prompt:
|
|
164
|
+
ag._no_tool_call_count = 0
|
|
124
165
|
continue
|
|
125
166
|
|
|
126
167
|
# 检查自动完成
|
|
127
168
|
if ag.auto_complete and is_auto_complete(current_response):
|
|
169
|
+
ag._no_tool_call_count = 0
|
|
128
170
|
# 先运行_complete_task,触发记忆整理/事件等副作用,再决定返回值
|
|
129
171
|
result = ag._complete_task(auto_completed=True)
|
|
130
172
|
# 若不需要summary,则将最后一条LLM输出作为返回值
|
|
@@ -132,6 +174,27 @@ class AgentRunLoop:
|
|
|
132
174
|
return current_response
|
|
133
175
|
return result
|
|
134
176
|
|
|
177
|
+
|
|
178
|
+
# 检查是否有工具调用:如果tool_prompt不为空,说明有工具被调用
|
|
179
|
+
has_tool_call = bool(safe_tool_prompt and safe_tool_prompt.strip())
|
|
180
|
+
|
|
181
|
+
# 在非交互模式下,跟踪连续没有工具调用的次数
|
|
182
|
+
if ag.non_interactive:
|
|
183
|
+
if has_tool_call:
|
|
184
|
+
# 有工具调用,重置计数器
|
|
185
|
+
ag._no_tool_call_count = 0
|
|
186
|
+
else:
|
|
187
|
+
# 没有工具调用,增加计数器
|
|
188
|
+
ag._no_tool_call_count += 1
|
|
189
|
+
# 如果连续5次没有工具调用,添加工具使用提示
|
|
190
|
+
if ag._no_tool_call_count >= 5:
|
|
191
|
+
tool_usage_prompt = ag.get_tool_usage_prompt()
|
|
192
|
+
ag.session.addon_prompt = join_prompts(
|
|
193
|
+
[ag.session.addon_prompt, tool_usage_prompt]
|
|
194
|
+
)
|
|
195
|
+
# 重置计数器,避免重复添加
|
|
196
|
+
ag._no_tool_call_count = 0
|
|
197
|
+
|
|
135
198
|
# 获取下一步用户输入
|
|
136
199
|
next_action = ag._get_next_user_action()
|
|
137
200
|
action = normalize_next_action(next_action)
|
|
@@ -142,5 +205,5 @@ class AgentRunLoop:
|
|
|
142
205
|
return ag._complete_task(auto_completed=False)
|
|
143
206
|
|
|
144
207
|
except Exception as e:
|
|
145
|
-
|
|
208
|
+
print(f"❌ 任务失败: {str(e)}")
|
|
146
209
|
return f"Task failed: {str(e)}"
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
import os
|
|
3
3
|
from typing import Any, Dict, Optional, TYPE_CHECKING
|
|
4
4
|
|
|
5
|
-
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
6
5
|
|
|
7
6
|
if TYPE_CHECKING:
|
|
8
7
|
from jarvis.jarvis_platform.base import BasePlatform
|
|
@@ -61,9 +60,9 @@ class SessionManager:
|
|
|
61
60
|
if self.model.restore(session_file):
|
|
62
61
|
try:
|
|
63
62
|
os.remove(session_file)
|
|
64
|
-
|
|
63
|
+
print("✅ 会话已恢复,并已删除会话文件。")
|
|
65
64
|
except OSError as e:
|
|
66
|
-
|
|
65
|
+
print(f"❌ 删除会话文件失败: {e}")
|
|
67
66
|
return True
|
|
68
67
|
return False
|
|
69
68
|
|