jarvis-ai-assistant 0.3.30__py3-none-any.whl → 0.7.0__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 +289 -87
- jarvis/jarvis_agent/agent_manager.py +17 -8
- jarvis/jarvis_agent/edit_file_handler.py +374 -86
- jarvis/jarvis_agent/event_bus.py +1 -1
- jarvis/jarvis_agent/file_context_handler.py +79 -0
- jarvis/jarvis_agent/jarvis.py +601 -43
- jarvis/jarvis_agent/main.py +32 -2
- jarvis/jarvis_agent/rewrite_file_handler.py +141 -0
- jarvis/jarvis_agent/run_loop.py +38 -5
- jarvis/jarvis_agent/share_manager.py +8 -1
- jarvis/jarvis_agent/stdio_redirect.py +295 -0
- jarvis/jarvis_agent/task_analyzer.py +5 -2
- jarvis/jarvis_agent/task_planner.py +496 -0
- jarvis/jarvis_agent/utils.py +5 -1
- jarvis/jarvis_agent/web_bridge.py +189 -0
- jarvis/jarvis_agent/web_output_sink.py +53 -0
- jarvis/jarvis_agent/web_server.py +751 -0
- jarvis/jarvis_c2rust/__init__.py +26 -0
- jarvis/jarvis_c2rust/cli.py +613 -0
- jarvis/jarvis_c2rust/collector.py +258 -0
- jarvis/jarvis_c2rust/library_replacer.py +1122 -0
- jarvis/jarvis_c2rust/llm_module_agent.py +1300 -0
- jarvis/jarvis_c2rust/optimizer.py +960 -0
- jarvis/jarvis_c2rust/scanner.py +1681 -0
- jarvis/jarvis_c2rust/transpiler.py +2325 -0
- jarvis/jarvis_code_agent/build_validation_config.py +133 -0
- jarvis/jarvis_code_agent/code_agent.py +1171 -94
- jarvis/jarvis_code_agent/code_analyzer/__init__.py +62 -0
- jarvis/jarvis_code_agent/code_analyzer/base_language.py +74 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/__init__.py +44 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/base.py +102 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/cmake.py +59 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/detector.py +125 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/fallback.py +69 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/go.py +38 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_gradle.py +44 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/java_maven.py +38 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/makefile.py +50 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/nodejs.py +93 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/python.py +129 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/rust.py +54 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator/validator.py +154 -0
- jarvis/jarvis_code_agent/code_analyzer/build_validator.py +43 -0
- jarvis/jarvis_code_agent/code_analyzer/context_manager.py +363 -0
- jarvis/jarvis_code_agent/code_analyzer/context_recommender.py +18 -0
- jarvis/jarvis_code_agent/code_analyzer/dependency_analyzer.py +132 -0
- jarvis/jarvis_code_agent/code_analyzer/file_ignore.py +330 -0
- jarvis/jarvis_code_agent/code_analyzer/impact_analyzer.py +781 -0
- jarvis/jarvis_code_agent/code_analyzer/language_registry.py +185 -0
- jarvis/jarvis_code_agent/code_analyzer/language_support.py +89 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/__init__.py +31 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/c_cpp_language.py +231 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/go_language.py +183 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/python_language.py +219 -0
- jarvis/jarvis_code_agent/code_analyzer/languages/rust_language.py +209 -0
- jarvis/jarvis_code_agent/code_analyzer/llm_context_recommender.py +451 -0
- jarvis/jarvis_code_agent/code_analyzer/symbol_extractor.py +77 -0
- jarvis/jarvis_code_agent/code_analyzer/tree_sitter_extractor.py +48 -0
- jarvis/jarvis_code_agent/lint.py +270 -8
- jarvis/jarvis_code_agent/utils.py +142 -0
- jarvis/jarvis_code_analysis/code_review.py +483 -569
- jarvis/jarvis_data/config_schema.json +97 -8
- jarvis/jarvis_git_utils/git_commiter.py +38 -26
- jarvis/jarvis_mcp/sse_mcp_client.py +2 -2
- jarvis/jarvis_mcp/stdio_mcp_client.py +1 -1
- jarvis/jarvis_memory_organizer/memory_organizer.py +1 -1
- jarvis/jarvis_multi_agent/__init__.py +239 -25
- jarvis/jarvis_multi_agent/main.py +37 -1
- jarvis/jarvis_platform/base.py +103 -51
- jarvis/jarvis_platform/openai.py +26 -1
- jarvis/jarvis_platform/yuanbao.py +1 -1
- jarvis/jarvis_platform_manager/service.py +2 -2
- jarvis/jarvis_rag/cli.py +4 -4
- jarvis/jarvis_sec/__init__.py +3605 -0
- jarvis/jarvis_sec/checkers/__init__.py +32 -0
- jarvis/jarvis_sec/checkers/c_checker.py +2680 -0
- jarvis/jarvis_sec/checkers/rust_checker.py +1108 -0
- jarvis/jarvis_sec/cli.py +116 -0
- jarvis/jarvis_sec/report.py +257 -0
- jarvis/jarvis_sec/status.py +264 -0
- jarvis/jarvis_sec/types.py +20 -0
- jarvis/jarvis_sec/workflow.py +219 -0
- jarvis/jarvis_stats/cli.py +1 -1
- jarvis/jarvis_stats/stats.py +1 -1
- jarvis/jarvis_stats/visualizer.py +1 -1
- jarvis/jarvis_tools/cli/main.py +1 -0
- jarvis/jarvis_tools/execute_script.py +46 -9
- jarvis/jarvis_tools/generate_new_tool.py +3 -1
- jarvis/jarvis_tools/read_code.py +275 -12
- jarvis/jarvis_tools/read_symbols.py +141 -0
- jarvis/jarvis_tools/read_webpage.py +5 -3
- jarvis/jarvis_tools/registry.py +73 -35
- jarvis/jarvis_tools/search_web.py +15 -11
- jarvis/jarvis_tools/sub_agent.py +24 -42
- jarvis/jarvis_tools/sub_code_agent.py +14 -13
- jarvis/jarvis_tools/virtual_tty.py +1 -1
- jarvis/jarvis_utils/config.py +187 -35
- jarvis/jarvis_utils/embedding.py +3 -0
- jarvis/jarvis_utils/git_utils.py +181 -6
- jarvis/jarvis_utils/globals.py +3 -3
- jarvis/jarvis_utils/http.py +1 -1
- jarvis/jarvis_utils/input.py +78 -2
- jarvis/jarvis_utils/methodology.py +25 -19
- jarvis/jarvis_utils/utils.py +644 -359
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/METADATA +85 -1
- jarvis_ai_assistant-0.7.0.dist-info/RECORD +192 -0
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/entry_points.txt +4 -0
- jarvis/jarvis_agent/config.py +0 -92
- jarvis/jarvis_tools/edit_file.py +0 -179
- jarvis/jarvis_tools/rewrite_file.py +0 -191
- jarvis_ai_assistant-0.3.30.dist-info/RECORD +0 -137
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.3.30.dist-info → jarvis_ai_assistant-0.7.0.dist-info}/top_level.txt +0 -0
jarvis/jarvis_tools/registry.py
CHANGED
|
@@ -51,6 +51,7 @@ arguments:
|
|
|
51
51
|
- 完全按照上述格式
|
|
52
52
|
- 使用正确的YAML格式,2个空格作为缩进
|
|
53
53
|
- 包含所有必需参数
|
|
54
|
+
- {ot("TOOL_CALL")} 和 {ct("TOOL_CALL")} 必须出现在行首
|
|
54
55
|
</rule>
|
|
55
56
|
|
|
56
57
|
<rule>
|
|
@@ -101,6 +102,7 @@ arguments:
|
|
|
101
102
|
- 创建虚构对话
|
|
102
103
|
- 在没有所需信息的情况下继续
|
|
103
104
|
- yaml 格式错误
|
|
105
|
+
- {ot("TOOL_CALL")} 和 {ct("TOOL_CALL")} 没有出现在行首
|
|
104
106
|
</common_errors>
|
|
105
107
|
</tool_system_guide>
|
|
106
108
|
"""
|
|
@@ -121,7 +123,8 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
|
121
123
|
return "TOOL_CALL"
|
|
122
124
|
|
|
123
125
|
def can_handle(self, response: str) -> bool:
|
|
124
|
-
|
|
126
|
+
# 仅当 {ot("TOOL_CALL")} 出现在行首时才认为可以处理
|
|
127
|
+
return re.search(rf'(?m){re.escape(ot("TOOL_CALL"))}', response) is not None
|
|
125
128
|
|
|
126
129
|
def prompt(self) -> str:
|
|
127
130
|
"""加载工具"""
|
|
@@ -172,7 +175,15 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
|
172
175
|
try:
|
|
173
176
|
tool_call, err_msg, auto_completed = self._extract_tool_calls(response)
|
|
174
177
|
if err_msg:
|
|
175
|
-
|
|
178
|
+
# 只要工具解析错误,追加工具使用帮助信息(相当于一次 <ToolUsage>)
|
|
179
|
+
try:
|
|
180
|
+
from jarvis.jarvis_agent import Agent
|
|
181
|
+
agent: Agent = agent_
|
|
182
|
+
tool_usage = agent.get_tool_usage_prompt()
|
|
183
|
+
return False, f"{err_msg}\n\n{tool_usage}"
|
|
184
|
+
except Exception:
|
|
185
|
+
# 兼容处理:无法获取Agent或ToolUsage时,至少返回工具系统帮助信息
|
|
186
|
+
return False, f"{err_msg}\n\n{tool_call_help}"
|
|
176
187
|
result = self.handle_tool_calls(tool_call, agent_)
|
|
177
188
|
if auto_completed:
|
|
178
189
|
# 如果自动补全了结束标签,在结果中添加说明信息
|
|
@@ -347,22 +358,28 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
|
347
358
|
# 如果配置了中心工具仓库,将其添加到加载路径
|
|
348
359
|
central_repo = get_central_tool_repo()
|
|
349
360
|
if central_repo:
|
|
350
|
-
#
|
|
351
|
-
|
|
352
|
-
|
|
361
|
+
# 支持本地目录路径或Git仓库URL
|
|
362
|
+
expanded = os.path.expanduser(os.path.expandvars(central_repo))
|
|
363
|
+
if os.path.isdir(expanded):
|
|
364
|
+
# 直接使用本地目录(支持Git仓库的子目录)
|
|
365
|
+
tool_dirs.append(expanded)
|
|
366
|
+
else:
|
|
367
|
+
# 中心工具仓库存储在数据目录下的特定位置
|
|
368
|
+
central_repo_path = os.path.join(get_data_dir(), "central_tool_repo")
|
|
369
|
+
tool_dirs.append(central_repo_path)
|
|
353
370
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
371
|
+
# 确保中心工具仓库被克隆/更新
|
|
372
|
+
if not os.path.exists(central_repo_path):
|
|
373
|
+
try:
|
|
374
|
+
import subprocess
|
|
358
375
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
376
|
+
subprocess.run(
|
|
377
|
+
["git", "clone", central_repo, central_repo_path], check=True
|
|
378
|
+
)
|
|
379
|
+
except Exception as e:
|
|
380
|
+
PrettyOutput.print(
|
|
381
|
+
f"克隆中心工具仓库失败: {str(e)}", OutputType.ERROR
|
|
382
|
+
)
|
|
366
383
|
|
|
367
384
|
# --- 全局每日更新检查 ---
|
|
368
385
|
daily_check_git_updates(tool_dirs, "tools")
|
|
@@ -608,11 +625,9 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
|
608
625
|
|
|
609
626
|
@staticmethod
|
|
610
627
|
def _has_tool_calls_block(content: str) -> bool:
|
|
611
|
-
"""
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
is not None
|
|
615
|
-
)
|
|
628
|
+
"""从内容中提取工具调用块(仅匹配行首标签)"""
|
|
629
|
+
pattern = rf'(?ms){re.escape(ot("TOOL_CALL"))}(.*?)^{re.escape(ct("TOOL_CALL"))}'
|
|
630
|
+
return re.search(pattern, content) is not None
|
|
616
631
|
|
|
617
632
|
@staticmethod
|
|
618
633
|
def _extract_tool_calls(
|
|
@@ -632,23 +647,29 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
|
632
647
|
异常:
|
|
633
648
|
Exception: 如果工具调用缺少必要字段
|
|
634
649
|
"""
|
|
650
|
+
# 如果</TOOL_CALL>出现在响应的末尾,但是前面没有换行符,自动插入一个换行符进行修复
|
|
651
|
+
if content.rstrip().endswith(ct("TOOL_CALL")):
|
|
652
|
+
pos = content.rfind(ct("TOOL_CALL"))
|
|
653
|
+
if pos > 0 and content[pos - 1] not in ("\n", "\r"):
|
|
654
|
+
content = content[:pos] + "\n" + content[pos:]
|
|
655
|
+
|
|
635
656
|
# 将内容拆分为行
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
)
|
|
657
|
+
pattern = rf'(?ms){re.escape(ot("TOOL_CALL"))}(.*?)^{re.escape(ct("TOOL_CALL"))}'
|
|
658
|
+
data = re.findall(pattern, content)
|
|
639
659
|
auto_completed = False
|
|
640
660
|
if not data:
|
|
641
|
-
# can_handle 确保 ot("TOOL_CALL")
|
|
642
|
-
#
|
|
643
|
-
|
|
644
|
-
|
|
661
|
+
# can_handle 确保 ot("TOOL_CALL") 在内容中(行首)。
|
|
662
|
+
# 如果数据为空,则表示行首的 ct("TOOL_CALL") 可能丢失。
|
|
663
|
+
has_open_at_bol = re.search(rf'(?m){re.escape(ot("TOOL_CALL"))}', content) is not None
|
|
664
|
+
has_close_at_bol = re.search(rf'(?m)^{re.escape(ct("TOOL_CALL"))}', content) is not None
|
|
665
|
+
if has_open_at_bol and not has_close_at_bol:
|
|
666
|
+
# 尝试通过附加结束标签来修复它(确保结束标签位于行首)
|
|
645
667
|
fixed_content = content.strip() + f"\n{ct('TOOL_CALL')}"
|
|
646
668
|
|
|
647
669
|
# 再次提取,并检查YAML是否有效
|
|
648
670
|
temp_data = re.findall(
|
|
649
|
-
|
|
671
|
+
pattern,
|
|
650
672
|
fixed_content,
|
|
651
|
-
re.DOTALL,
|
|
652
673
|
)
|
|
653
674
|
|
|
654
675
|
if temp_data:
|
|
@@ -830,10 +851,12 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
|
830
851
|
try:
|
|
831
852
|
args = json.loads(args)
|
|
832
853
|
except json.JSONDecodeError:
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
854
|
+
# 返回错误并附带完整的工具使用提示,指导下一次正确调用
|
|
855
|
+
try:
|
|
856
|
+
usage_prompt = agent_instance.get_tool_usage_prompt()
|
|
857
|
+
except Exception:
|
|
858
|
+
usage_prompt = tool_call_help
|
|
859
|
+
return f"工具参数格式无效: {name}。arguments 应为可解析的 JSON 或对象,请按工具调用格式提供。\n\n{usage_prompt}"
|
|
837
860
|
|
|
838
861
|
# 执行工具调用(根据工具实现的协议版本,由系统在内部决定agent的传递方式)
|
|
839
862
|
result = self.execute_tool(name, args, agent)
|
|
@@ -853,6 +876,15 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
|
853
876
|
except Exception:
|
|
854
877
|
pass
|
|
855
878
|
|
|
879
|
+
# 如果执行失败,附带工具使用提示返回
|
|
880
|
+
if not result.get("success", False):
|
|
881
|
+
try:
|
|
882
|
+
usage_prompt = agent_instance.get_tool_usage_prompt()
|
|
883
|
+
except Exception:
|
|
884
|
+
usage_prompt = tool_call_help
|
|
885
|
+
err_output = self._format_tool_output(result.get("stdout", ""), result.get("stderr", ""))
|
|
886
|
+
return f"{err_output}\n\n{usage_prompt}"
|
|
887
|
+
|
|
856
888
|
# 格式化输出
|
|
857
889
|
output = self._format_tool_output(
|
|
858
890
|
result["stdout"], result.get("stderr", "")
|
|
@@ -913,4 +945,10 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
|
913
945
|
|
|
914
946
|
except Exception as e:
|
|
915
947
|
PrettyOutput.print(f"工具执行失败:{str(e)}", OutputType.ERROR)
|
|
916
|
-
|
|
948
|
+
try:
|
|
949
|
+
from jarvis.jarvis_agent import Agent # 延迟导入避免循环依赖
|
|
950
|
+
agent_instance_for_prompt: Agent = agent # type: ignore
|
|
951
|
+
usage_prompt = agent_instance_for_prompt.get_tool_usage_prompt()
|
|
952
|
+
except Exception:
|
|
953
|
+
usage_prompt = tool_call_help
|
|
954
|
+
return f"工具调用失败: {str(e)}\n\n{usage_prompt}"
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"""网络搜索工具。"""
|
|
3
3
|
from typing import Any, Dict
|
|
4
4
|
|
|
5
|
-
import requests
|
|
5
|
+
import requests # type: ignore[import-untyped]
|
|
6
6
|
from markdownify import markdownify as md # type: ignore
|
|
7
7
|
|
|
8
8
|
# pylint: disable=import-error,missing-module-docstring
|
|
@@ -147,11 +147,13 @@ class SearchWebTool:
|
|
|
147
147
|
if model.support_web():
|
|
148
148
|
model.set_web(True)
|
|
149
149
|
model.set_suppress_output(False)
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
150
|
+
response = model.chat_until_success(query)
|
|
151
|
+
if response and response.strip():
|
|
152
|
+
return {
|
|
153
|
+
"stdout": response,
|
|
154
|
+
"stderr": "",
|
|
155
|
+
"success": True,
|
|
156
|
+
}
|
|
155
157
|
|
|
156
158
|
# 否则使用现有的模型选择流程
|
|
157
159
|
if agent.model.support_web():
|
|
@@ -161,11 +163,13 @@ class SearchWebTool:
|
|
|
161
163
|
model.set_model_name(agent.model.name())
|
|
162
164
|
model.set_web(True)
|
|
163
165
|
model.set_suppress_output(False)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
response = model.chat_until_success(query)
|
|
167
|
+
if response and response.strip():
|
|
168
|
+
return {
|
|
169
|
+
"stdout": response,
|
|
170
|
+
"stderr": "",
|
|
171
|
+
"success": True,
|
|
172
|
+
}
|
|
169
173
|
|
|
170
174
|
return self._search_with_ddgs(query, agent)
|
|
171
175
|
|
jarvis/jarvis_tools/sub_agent.py
CHANGED
|
@@ -4,16 +4,17 @@ sub_agent 工具
|
|
|
4
4
|
将子任务交给通用 Agent 执行,并返回执行结果。
|
|
5
5
|
|
|
6
6
|
约定:
|
|
7
|
-
- 必填参数:task, name,
|
|
8
|
-
-
|
|
7
|
+
- 必填参数:task, name, system_prompt, summary_prompt
|
|
8
|
+
- 可选参数:background
|
|
9
|
+
- 工具集:默认使用系统工具集(无需传入 use_tools)
|
|
10
|
+
- 继承父 Agent 的部分配置:model_group、input_handler、execute_tool_confirm、multiline_inputer、non_interactive、use_methodology、use_analysis;其他参数需显式提供
|
|
9
11
|
- 子Agent必须自动完成(auto_complete=True)且需要summary(need_summary=True)
|
|
10
12
|
"""
|
|
11
|
-
from typing import Any, Dict
|
|
13
|
+
from typing import Any, Dict
|
|
12
14
|
import json
|
|
13
15
|
|
|
14
16
|
from jarvis.jarvis_agent import Agent
|
|
15
17
|
from jarvis.jarvis_utils.globals import delete_agent
|
|
16
|
-
from jarvis.jarvis_tools.registry import ToolRegistry
|
|
17
18
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
18
19
|
|
|
19
20
|
|
|
@@ -27,7 +28,7 @@ class SubAgentTool:
|
|
|
27
28
|
|
|
28
29
|
# 必须与文件名一致,供 ToolRegistry 自动注册
|
|
29
30
|
name = "sub_agent"
|
|
30
|
-
description = "将子任务交给通用 Agent 执行,并返回执行结果(继承父Agent部分配置:model_group、input_handler、execute_tool_confirm、multiline_inputer;其他参数需显式提供,自动完成并生成总结)。"
|
|
31
|
+
description = "将子任务交给通用 Agent 执行,并返回执行结果(继承父Agent部分配置:model_group、input_handler、execute_tool_confirm、multiline_inputer、non_interactive、use_methodology、use_analysis;其他参数需显式提供,自动完成并生成总结)。"
|
|
31
32
|
parameters = {
|
|
32
33
|
"type": "object",
|
|
33
34
|
"properties": {
|
|
@@ -41,7 +42,7 @@ class SubAgentTool:
|
|
|
41
42
|
},
|
|
42
43
|
"background": {
|
|
43
44
|
"type": "string",
|
|
44
|
-
"description": "
|
|
45
|
+
"description": "任务背景与已知信息(可选,将与任务一并提供给子Agent)",
|
|
45
46
|
},
|
|
46
47
|
"system_prompt": {
|
|
47
48
|
"type": "string",
|
|
@@ -51,25 +52,16 @@ class SubAgentTool:
|
|
|
51
52
|
"type": "string",
|
|
52
53
|
"description": "覆盖子Agent的总结提示词(必填)",
|
|
53
54
|
},
|
|
54
|
-
"
|
|
55
|
-
"type": "
|
|
56
|
-
"
|
|
57
|
-
"description": "限制子Agent可用的工具名称列表(必填)。兼容以逗号分隔的字符串输入。可用的工具列表:"
|
|
58
|
-
+ "\n".join(
|
|
59
|
-
[
|
|
60
|
-
t["name"] + ": " + t["description"]
|
|
61
|
-
for t in ToolRegistry().get_all_tools()
|
|
62
|
-
]
|
|
63
|
-
),
|
|
55
|
+
"non_interactive": {
|
|
56
|
+
"type": "boolean",
|
|
57
|
+
"description": "是否启用无交互模式(可选,默认继承父Agent或系统默认)",
|
|
64
58
|
},
|
|
65
59
|
},
|
|
66
60
|
"required": [
|
|
67
61
|
"task",
|
|
68
62
|
"name",
|
|
69
|
-
"background",
|
|
70
63
|
"system_prompt",
|
|
71
64
|
"summary_prompt",
|
|
72
|
-
"use_tools",
|
|
73
65
|
],
|
|
74
66
|
}
|
|
75
67
|
|
|
@@ -105,16 +97,6 @@ class SubAgentTool:
|
|
|
105
97
|
summary_prompt = str(args.get("summary_prompt", "")).strip()
|
|
106
98
|
agent_name = str(args.get("name", "")).strip()
|
|
107
99
|
|
|
108
|
-
# 解析可用工具列表(支持数组或以逗号分隔的字符串)
|
|
109
|
-
_use_tools = args.get("use_tools", None)
|
|
110
|
-
use_tools: List[str] = []
|
|
111
|
-
if isinstance(_use_tools, list):
|
|
112
|
-
use_tools = [str(x).strip() for x in _use_tools if str(x).strip()]
|
|
113
|
-
elif isinstance(_use_tools, str):
|
|
114
|
-
use_tools = [s.strip() for s in _use_tools.split(",") if s.strip()]
|
|
115
|
-
else:
|
|
116
|
-
use_tools = []
|
|
117
|
-
|
|
118
100
|
errors = []
|
|
119
101
|
if not system_prompt:
|
|
120
102
|
errors.append("system_prompt 不能为空")
|
|
@@ -122,8 +104,6 @@ class SubAgentTool:
|
|
|
122
104
|
errors.append("summary_prompt 不能为空")
|
|
123
105
|
if not agent_name:
|
|
124
106
|
errors.append("name 不能为空")
|
|
125
|
-
if not use_tools:
|
|
126
|
-
errors.append("use_tools 不能为空")
|
|
127
107
|
if not background:
|
|
128
108
|
errors.append("background 不能为空")
|
|
129
109
|
|
|
@@ -137,20 +117,29 @@ class SubAgentTool:
|
|
|
137
117
|
# 基于父Agent(如有)继承部分配置后创建子Agent
|
|
138
118
|
parent_agent = args.get("agent", None)
|
|
139
119
|
parent_model_group = None
|
|
140
|
-
parent_input_handler = None
|
|
141
120
|
parent_execute_tool_confirm = None
|
|
142
121
|
parent_multiline_inputer = None
|
|
122
|
+
parent_non_interactive = None
|
|
123
|
+
parent_use_methodology = None
|
|
124
|
+
parent_use_analysis = None
|
|
143
125
|
try:
|
|
144
126
|
if parent_agent is not None:
|
|
145
127
|
if getattr(parent_agent, "model", None):
|
|
146
128
|
parent_model_group = getattr(parent_agent.model, "model_group", None)
|
|
147
|
-
parent_input_handler = getattr(parent_agent, "input_handler", None)
|
|
148
129
|
parent_execute_tool_confirm = getattr(parent_agent, "execute_tool_confirm", None)
|
|
149
130
|
parent_multiline_inputer = getattr(parent_agent, "multiline_inputer", None)
|
|
131
|
+
parent_non_interactive = getattr(parent_agent, "non_interactive", None)
|
|
132
|
+
parent_use_methodology = getattr(parent_agent, "use_methodology", None)
|
|
133
|
+
parent_use_analysis = getattr(parent_agent, "use_analysis", None)
|
|
150
134
|
except Exception:
|
|
151
135
|
# 安全兜底:无法从父Agent获取配置则保持为None,使用系统默认
|
|
152
136
|
pass
|
|
153
137
|
|
|
138
|
+
# 可选参数:允许显式覆盖无交互模式
|
|
139
|
+
explicit_non_interactive = args.get("non_interactive", None)
|
|
140
|
+
if explicit_non_interactive is not None:
|
|
141
|
+
parent_non_interactive = bool(explicit_non_interactive)
|
|
142
|
+
|
|
154
143
|
agent = Agent(
|
|
155
144
|
system_prompt=system_prompt,
|
|
156
145
|
name=agent_name,
|
|
@@ -158,24 +147,17 @@ class SubAgentTool:
|
|
|
158
147
|
model_group=parent_model_group,
|
|
159
148
|
summary_prompt=summary_prompt,
|
|
160
149
|
auto_complete=auto_complete,
|
|
161
|
-
output_handler=None,
|
|
162
150
|
use_tools=None,
|
|
163
|
-
input_handler=parent_input_handler,
|
|
164
151
|
execute_tool_confirm=parent_execute_tool_confirm,
|
|
165
152
|
need_summary=need_summary,
|
|
166
153
|
multiline_inputer=parent_multiline_inputer,
|
|
167
|
-
use_methodology=
|
|
168
|
-
use_analysis=
|
|
154
|
+
use_methodology=parent_use_methodology,
|
|
155
|
+
use_analysis=parent_use_analysis,
|
|
169
156
|
force_save_memory=None,
|
|
170
157
|
files=None,
|
|
158
|
+
non_interactive=parent_non_interactive,
|
|
171
159
|
)
|
|
172
160
|
|
|
173
|
-
# 设置可用工具列表
|
|
174
|
-
try:
|
|
175
|
-
agent.set_use_tools(use_tools)
|
|
176
|
-
except Exception:
|
|
177
|
-
pass
|
|
178
|
-
|
|
179
161
|
# 校验子Agent所用模型是否有效,必要时回退到平台可用模型
|
|
180
162
|
try:
|
|
181
163
|
platform = getattr(agent, "model", None)
|
|
@@ -4,12 +4,12 @@ sub_code_agent 工具
|
|
|
4
4
|
将子任务交给 CodeAgent 执行,并返回执行结果。
|
|
5
5
|
|
|
6
6
|
约定:
|
|
7
|
-
-
|
|
7
|
+
- 必填参数:task
|
|
8
|
+
- 可选参数:background
|
|
8
9
|
- 不依赖父 Agent,所有配置使用系统默认与全局变量
|
|
9
10
|
- 子Agent必须自动完成(auto_complete=True)且需要summary(need_summary=True)
|
|
10
11
|
"""
|
|
11
12
|
from typing import Any, Dict, List
|
|
12
|
-
import json
|
|
13
13
|
|
|
14
14
|
from jarvis.jarvis_code_agent.code_agent import CodeAgent
|
|
15
15
|
from jarvis.jarvis_utils.globals import delete_agent
|
|
@@ -19,7 +19,7 @@ from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
|
|
19
19
|
|
|
20
20
|
class SubCodeAgentTool:
|
|
21
21
|
"""
|
|
22
|
-
使用 CodeAgent
|
|
22
|
+
使用 CodeAgent 托管执行子任务,执行完立即清理 CodeAgent 实例。
|
|
23
23
|
- 不注册至全局
|
|
24
24
|
- 使用系统默认/全局配置
|
|
25
25
|
- 启用自动完成与总结
|
|
@@ -84,6 +84,7 @@ class SubCodeAgentTool:
|
|
|
84
84
|
parent_agent = None
|
|
85
85
|
except Exception:
|
|
86
86
|
parent_agent = None
|
|
87
|
+
parent_non_interactive = getattr(parent_agent, "non_interactive", None) if parent_agent is not None else None
|
|
87
88
|
model_group = None
|
|
88
89
|
use_tools: List[str] = []
|
|
89
90
|
try:
|
|
@@ -115,7 +116,7 @@ class SubCodeAgentTool:
|
|
|
115
116
|
"search_web",
|
|
116
117
|
"ask_user",
|
|
117
118
|
"read_code",
|
|
118
|
-
|
|
119
|
+
|
|
119
120
|
"save_memory",
|
|
120
121
|
"retrieve_memory",
|
|
121
122
|
"clear_memory",
|
|
@@ -138,6 +139,7 @@ class SubCodeAgentTool:
|
|
|
138
139
|
need_summary=True,
|
|
139
140
|
append_tools=append_tools,
|
|
140
141
|
tool_group=tool_group,
|
|
142
|
+
non_interactive=parent_non_interactive,
|
|
141
143
|
)
|
|
142
144
|
except SystemExit as se:
|
|
143
145
|
# 将底层 sys.exit 转换为工具错误,避免终止进程
|
|
@@ -155,21 +157,21 @@ class SubCodeAgentTool:
|
|
|
155
157
|
|
|
156
158
|
# 子Agent需要自动完成
|
|
157
159
|
try:
|
|
158
|
-
code_agent.
|
|
160
|
+
code_agent.auto_complete = True
|
|
159
161
|
# 同步父Agent工具使用集(如可用)
|
|
160
162
|
if use_tools:
|
|
161
|
-
code_agent.
|
|
163
|
+
code_agent.set_use_tools(use_tools)
|
|
162
164
|
# 同步父Agent的模型名称(如可用),以尽量保持平台与模型一致
|
|
163
165
|
if (
|
|
164
166
|
parent_agent is not None
|
|
165
167
|
and getattr(parent_agent, "model", None)
|
|
166
|
-
and getattr(code_agent
|
|
168
|
+
and getattr(code_agent, "model", None)
|
|
167
169
|
):
|
|
168
170
|
try:
|
|
169
171
|
parent_model_name = parent_agent.model.name() # type: ignore[attr-defined]
|
|
170
172
|
if parent_model_name:
|
|
171
173
|
from typing import Any
|
|
172
|
-
model_obj: Any = getattr(code_agent
|
|
174
|
+
model_obj: Any = getattr(code_agent, "model", None)
|
|
173
175
|
if model_obj is not None:
|
|
174
176
|
model_obj.set_model_name(parent_model_name)
|
|
175
177
|
# 模型有效性校验与回退,确保父Agent模型在子Agent平台上可用
|
|
@@ -194,18 +196,17 @@ class SubCodeAgentTool:
|
|
|
194
196
|
|
|
195
197
|
# 执行子任务(无提交信息前后缀)
|
|
196
198
|
ret = code_agent.run(enhanced_task, prefix="", suffix="")
|
|
197
|
-
stdout = ret if isinstance(ret, str) and ret else "任务执行完成"
|
|
198
199
|
|
|
199
|
-
#
|
|
200
|
+
# 主动清理 CodeAgent 实例,避免污染父Agent的全局状态
|
|
200
201
|
try:
|
|
201
|
-
|
|
202
|
-
delete_agent(
|
|
202
|
+
# CodeAgent 现在直接继承 Agent,所以直接使用 code_agent
|
|
203
|
+
delete_agent(code_agent.name)
|
|
203
204
|
except Exception:
|
|
204
205
|
pass
|
|
205
206
|
|
|
206
207
|
return {
|
|
207
208
|
"success": True,
|
|
208
|
-
"stdout":
|
|
209
|
+
"stdout": ret,
|
|
209
210
|
"stderr": "",
|
|
210
211
|
}
|
|
211
212
|
except Exception as e:
|