jarvis-ai-assistant 0.2.0__py3-none-any.whl → 0.2.1__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_multi_agent/__init__.py +7 -5
- jarvis/jarvis_tools/registry.py +59 -21
- {jarvis_ai_assistant-0.2.0.dist-info → jarvis_ai_assistant-0.2.1.dist-info}/METADATA +15 -3
- {jarvis_ai_assistant-0.2.0.dist-info → jarvis_ai_assistant-0.2.1.dist-info}/RECORD +9 -9
- {jarvis_ai_assistant-0.2.0.dist-info → jarvis_ai_assistant-0.2.1.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.2.0.dist-info → jarvis_ai_assistant-0.2.1.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.2.0.dist-info → jarvis_ai_assistant-0.2.1.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.2.0.dist-info → jarvis_ai_assistant-0.2.1.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
import re
|
3
|
-
from typing import Any, Dict, List, Optional, Tuple
|
3
|
+
from typing import Any, Dict, List, Optional, Tuple, Union
|
4
4
|
|
5
5
|
import yaml
|
6
6
|
|
@@ -89,6 +89,8 @@ content: |2
|
|
89
89
|
Args:
|
90
90
|
content: The content containing send message
|
91
91
|
"""
|
92
|
+
if ot("SEND_MESSAGE") in content and ct("SEND_MESSAGE") not in content:
|
93
|
+
content += "\n" + ct("SEND_MESSAGE")
|
92
94
|
data = re.findall(
|
93
95
|
ot("SEND_MESSAGE") + r"\n(.*?)\n" + ct("SEND_MESSAGE"), content, re.DOTALL
|
94
96
|
)
|
@@ -102,7 +104,7 @@ content: |2
|
|
102
104
|
continue
|
103
105
|
return ret
|
104
106
|
|
105
|
-
def _get_agent(self, name: str) -> Agent
|
107
|
+
def _get_agent(self, name: str) -> Union[Agent, None]:
|
106
108
|
if name in self.agents:
|
107
109
|
return self.agents[name]
|
108
110
|
|
@@ -113,9 +115,9 @@ content: |2
|
|
113
115
|
|
114
116
|
if name != self.main_agent_name and self.original_question:
|
115
117
|
system_prompt = config.get("system_prompt", "")
|
116
|
-
config[
|
117
|
-
|
118
|
-
|
118
|
+
config[
|
119
|
+
"system_prompt"
|
120
|
+
] = f"{system_prompt}\n\n# 原始问题\n{self.original_question}"
|
119
121
|
|
120
122
|
output_handler = config.get("output_handler", [])
|
121
123
|
if len(output_handler) == 0:
|
jarvis/jarvis_tools/registry.py
CHANGED
@@ -15,6 +15,7 @@ from jarvis.jarvis_mcp.stdio_mcp_client import StdioMcpClient
|
|
15
15
|
from jarvis.jarvis_mcp.streamable_mcp_client import StreamableMcpClient
|
16
16
|
from jarvis.jarvis_tools.base import Tool
|
17
17
|
from jarvis.jarvis_utils.config import get_data_dir, get_tool_load_dirs
|
18
|
+
from jarvis.jarvis_utils.input import user_confirm
|
18
19
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
19
20
|
from jarvis.jarvis_utils.tag import ct, ot
|
20
21
|
from jarvis.jarvis_utils.utils import is_context_overflow, daily_check_git_updates
|
@@ -106,14 +107,20 @@ arguments:
|
|
106
107
|
|
107
108
|
|
108
109
|
class OutputHandlerProtocol(Protocol):
|
109
|
-
def name(self) -> str:
|
110
|
-
|
111
|
-
def prompt(self) -> str: ...
|
112
|
-
def handle(self, response: str, agent: Any) -> Tuple[bool, Any]: ...
|
110
|
+
def name(self) -> str:
|
111
|
+
...
|
113
112
|
|
113
|
+
def can_handle(self, response: str) -> bool:
|
114
|
+
...
|
114
115
|
|
115
|
-
|
116
|
+
def prompt(self) -> str:
|
117
|
+
...
|
116
118
|
|
119
|
+
def handle(self, response: str, agent: Any) -> Tuple[bool, Any]:
|
120
|
+
...
|
121
|
+
|
122
|
+
|
123
|
+
class ToolRegistry(OutputHandlerProtocol):
|
117
124
|
def name(self) -> str:
|
118
125
|
return "TOOL_CALL"
|
119
126
|
|
@@ -124,14 +131,16 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
124
131
|
"""加载工具"""
|
125
132
|
tools = self.get_all_tools()
|
126
133
|
if tools:
|
127
|
-
tools_prompt = f"
|
134
|
+
tools_prompt = f"<tools_section>\n"
|
128
135
|
tools_prompt += " <header>## 可用工具:</header>\n"
|
129
136
|
tools_prompt += " <tools_list>\n"
|
130
137
|
for tool in tools:
|
131
138
|
try:
|
132
139
|
tools_prompt += " <tool>\n"
|
133
140
|
tools_prompt += f" <name>名称: {tool['name']}</name>\n"
|
134
|
-
tools_prompt +=
|
141
|
+
tools_prompt += (
|
142
|
+
f" <description>描述: {tool['description']}</description>\n"
|
143
|
+
)
|
135
144
|
tools_prompt += " <parameters>\n"
|
136
145
|
tools_prompt += " <yaml>|\n"
|
137
146
|
|
@@ -197,9 +206,7 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
197
206
|
with open(stats_file, "r", encoding="utf-8") as f:
|
198
207
|
return yaml.safe_load(f) or {}
|
199
208
|
except Exception as e:
|
200
|
-
PrettyOutput.print(
|
201
|
-
f"加载工具调用统计失败: {str(e)}", OutputType.WARNING
|
202
|
-
)
|
209
|
+
PrettyOutput.print(f"加载工具调用统计失败: {str(e)}", OutputType.WARNING)
|
203
210
|
return {}
|
204
211
|
|
205
212
|
def _update_tool_stats(self, name: str) -> None:
|
@@ -269,9 +276,7 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
269
276
|
config = yaml.safe_load(open(file_path, "r", encoding="utf-8"))
|
270
277
|
self.register_mcp_tool_by_config(config)
|
271
278
|
except Exception as e:
|
272
|
-
PrettyOutput.print(
|
273
|
-
f"文件 {file_path} 加载失败: {str(e)}", OutputType.WARNING
|
274
|
-
)
|
279
|
+
PrettyOutput.print(f"文件 {file_path} 加载失败: {str(e)}", OutputType.WARNING)
|
275
280
|
|
276
281
|
def _load_builtin_tools(self) -> None:
|
277
282
|
"""从内置工具目录加载工具"""
|
@@ -508,7 +513,6 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
508
513
|
and hasattr(item, "execute")
|
509
514
|
and item.name == module_name
|
510
515
|
):
|
511
|
-
|
512
516
|
if hasattr(item, "check"):
|
513
517
|
if not item.check():
|
514
518
|
continue
|
@@ -567,10 +571,46 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
567
571
|
ot("TOOL_CALL") + r"(.*?)" + ct("TOOL_CALL"), content, re.DOTALL
|
568
572
|
)
|
569
573
|
if not data:
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
+
# can_handle 确保 ot("TOOL_CALL") 在内容中。
|
575
|
+
# 如果数据为空,则表示 ct("TOOL_CALL") 可能丢失。
|
576
|
+
if ot("TOOL_CALL") in content and ct("TOOL_CALL") not in content:
|
577
|
+
# 尝试通过附加结束标签来修复它
|
578
|
+
fixed_content = content.strip() + f"\n{ct('TOOL_CALL')}"
|
579
|
+
|
580
|
+
# 再次提取,并检查YAML是否有效
|
581
|
+
temp_data = re.findall(
|
582
|
+
ot("TOOL_CALL") + r"(.*?)" + ct("TOOL_CALL"),
|
583
|
+
fixed_content,
|
584
|
+
re.DOTALL,
|
585
|
+
)
|
586
|
+
|
587
|
+
if temp_data:
|
588
|
+
try:
|
589
|
+
yaml.safe_load(temp_data[0]) # Check if valid YAML
|
590
|
+
|
591
|
+
# Ask user for confirmation
|
592
|
+
PrettyOutput.print(
|
593
|
+
f"检测到缺失的 {ct('TOOL_CALL')} 标签,已自动修复。修复后的内容如下:",
|
594
|
+
OutputType.INFO,
|
595
|
+
)
|
596
|
+
PrettyOutput.print(fixed_content, OutputType.TOOL)
|
597
|
+
if user_confirm("这是纠正后的,是否需要执行?", default=True):
|
598
|
+
data = temp_data
|
599
|
+
else:
|
600
|
+
return (
|
601
|
+
{},
|
602
|
+
f"只有{ot('TOOL_CALL')}标签,未找到{ct('TOOL_CALL')}标签,调用格式错误,请检查工具调用格式。\n{tool_call_help}",
|
603
|
+
)
|
604
|
+
except (yaml.YAMLError, EOFError, KeyboardInterrupt):
|
605
|
+
# Even after fixing, it's not valid YAML, or user cancelled.
|
606
|
+
# Fall through to the original error.
|
607
|
+
pass
|
608
|
+
|
609
|
+
if not data:
|
610
|
+
return (
|
611
|
+
{},
|
612
|
+
f"只有{ot('TOOL_CALL')}标签,未找到{ct('TOOL_CALL')}标签,调用格式错误,请检查工具调用格式。\n{tool_call_help}",
|
613
|
+
)
|
574
614
|
ret = []
|
575
615
|
for item in data:
|
576
616
|
try:
|
@@ -685,9 +725,7 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
685
725
|
"""
|
686
726
|
if len(output.splitlines()) > 60:
|
687
727
|
lines = output.splitlines()
|
688
|
-
return "\n".join(
|
689
|
-
lines[:30] + ["\n...内容太长,已截取前后30行...\n"] + lines[-30:]
|
690
|
-
)
|
728
|
+
return "\n".join(lines[:30] + ["\n...内容太长,已截取前后30行...\n"] + lines[-30:])
|
691
729
|
return output
|
692
730
|
|
693
731
|
def handle_tool_calls(self, tool_call: Dict[str, Any], agent: Any) -> str:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: jarvis-ai-assistant
|
3
|
-
Version: 0.2.
|
3
|
+
Version: 0.2.1
|
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
|
@@ -104,13 +104,25 @@ Dynamic: requires-python
|
|
104
104
|
- Windows没有测试过,但Windows 10以上的用户可以在WSL上使用此工具
|
105
105
|
|
106
106
|
### 安装
|
107
|
+
|
108
|
+
#### 一键安装 (推荐)
|
109
|
+
只需一行命令即可完成所有安装和配置:
|
110
|
+
```bash
|
111
|
+
bash -c "$(curl -fsSL https://raw.githubusercontent.com/skyfireitdiy/Jarvis/main/scripts/install.sh)"
|
112
|
+
```
|
113
|
+
> 该脚本会自动检测Python环境、克隆项目、安装依赖并设置好路径。
|
114
|
+
|
115
|
+
#### 手动安装
|
116
|
+
|
117
|
+
**1. 从源码安装**
|
107
118
|
```bash
|
108
|
-
# 从源码安装(推荐)
|
109
119
|
git clone https://github.com/skyfireitdiy/Jarvis
|
110
120
|
cd Jarvis
|
111
121
|
pip3 install -e .
|
122
|
+
```
|
112
123
|
|
113
|
-
|
124
|
+
**2. 从PyPI安装 (可能不是最新版)**
|
125
|
+
```bash
|
114
126
|
pip3 install jarvis-ai-assistant
|
115
127
|
```
|
116
128
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
jarvis/__init__.py,sha256=
|
1
|
+
jarvis/__init__.py,sha256=7YS_CmhWeXPE4rP8NAcZnRuHXCr7rFpRpDd4pK4v2GQ,73
|
2
2
|
jarvis/jarvis_agent/__init__.py,sha256=BmBbMUsCwe_0znrwxSipaKj-MuOgJTZvLbyKzBFfpic,22559
|
3
3
|
jarvis/jarvis_agent/builtin_input_handler.py,sha256=Qs4LAr4xdKLBJpQE81YP4CkucAop86ms0iVoKa1nnso,2468
|
4
4
|
jarvis/jarvis_agent/edit_file_handler.py,sha256=ml1o-BE2Ca1-ybPlKuhstLQYwdJag39o0_-PXTUvFaE,11646
|
@@ -47,7 +47,7 @@ jarvis/jarvis_mcp/sse_mcp_client.py,sha256=AhYLPQb0mE9-6ZQw1JesRNyEy0esJumNEFb5L
|
|
47
47
|
jarvis/jarvis_mcp/stdio_mcp_client.py,sha256=APYUksYKlMx7AVNODKOLrTkKZPnp4kqTQIYIuNDDKko,11286
|
48
48
|
jarvis/jarvis_mcp/streamable_mcp_client.py,sha256=1OZpsG82U2MLbGuojllJAblFUAMmp1N0i5fsKM4n5Ts,14453
|
49
49
|
jarvis/jarvis_methodology/main.py,sha256=-PqsWvtpUJkkhiGgV-1JegEnEZBmv8SHnNMNNm_-QQc,11720
|
50
|
-
jarvis/jarvis_multi_agent/__init__.py,sha256=
|
50
|
+
jarvis/jarvis_multi_agent/__init__.py,sha256=kCgtAX7VvliyEOQxIj2DvNjRAuh6bpNaOtDn60nzph4,6089
|
51
51
|
jarvis/jarvis_multi_agent/main.py,sha256=h7VUSwoPrES0XTK8z5kt3XLX1mmcm8UEuFEHQOUWPH4,1696
|
52
52
|
jarvis/jarvis_platform/__init__.py,sha256=WLQHSiE87PPket2M50_hHzjdMIgPIBx2VF8JfB_NNRk,105
|
53
53
|
jarvis/jarvis_platform/ai8.py,sha256=yi7xG8ld4Yrf7drz-uu_JT_XCGYRB0obhygt-jKik8o,10871
|
@@ -83,7 +83,7 @@ jarvis/jarvis_tools/generate_new_tool.py,sha256=ppMRuTYUZ0c02rHo7xi8DCGiDVPZTANV
|
|
83
83
|
jarvis/jarvis_tools/methodology.py,sha256=_K4GIDUodGEma3SvNRo7Qs5rliijgNespVLyAPN35JU,5233
|
84
84
|
jarvis/jarvis_tools/read_code.py,sha256=EnI-R-5HyIQYhMD391nZWXHIuHHBF-OJIRE0QpLcPX4,6417
|
85
85
|
jarvis/jarvis_tools/read_webpage.py,sha256=NmDUboVZd4CGHBPRFK6dp3uqVhuGopW1bOi3TcaLDF4,2092
|
86
|
-
jarvis/jarvis_tools/registry.py,sha256=
|
86
|
+
jarvis/jarvis_tools/registry.py,sha256=FO72qNhDXeBRMnLc9IR87X0SNqAkGkzbHYtbw-7OMgI,28604
|
87
87
|
jarvis/jarvis_tools/rewrite_file.py,sha256=eG_WKg6cVAXmuGwUqlWkcuyay5S8DOzEi8vZCmX3O8w,7255
|
88
88
|
jarvis/jarvis_tools/search_web.py,sha256=DDAPjYWTFaF85zsnhJ6VNDSc1BcY8EHus5ymKP9nnPs,5703
|
89
89
|
jarvis/jarvis_tools/virtual_tty.py,sha256=KKr3jpvQWWMPr2o40hlmN6fuXJCN8H4_ma5QU40Citc,16089
|
@@ -102,9 +102,9 @@ jarvis/jarvis_utils/methodology.py,sha256=V2Y0mbamrWBhhCK-3foAM1hKewOEcIDcXO-Sv_
|
|
102
102
|
jarvis/jarvis_utils/output.py,sha256=2QMpzb8ZOysQ6HHsRjRzjgUnNXaFGkIiZ_qElPKLbsA,10858
|
103
103
|
jarvis/jarvis_utils/tag.py,sha256=f211opbbbTcSyzCDwuIK_oCnKhXPNK-RknYyGzY1yD0,431
|
104
104
|
jarvis/jarvis_utils/utils.py,sha256=G6UuiBrPlWLpau1LbSGStrlAHCHG8JufINLD_bwtjTE,20006
|
105
|
-
jarvis_ai_assistant-0.2.
|
106
|
-
jarvis_ai_assistant-0.2.
|
107
|
-
jarvis_ai_assistant-0.2.
|
108
|
-
jarvis_ai_assistant-0.2.
|
109
|
-
jarvis_ai_assistant-0.2.
|
110
|
-
jarvis_ai_assistant-0.2.
|
105
|
+
jarvis_ai_assistant-0.2.1.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
106
|
+
jarvis_ai_assistant-0.2.1.dist-info/METADATA,sha256=2CaCKJhb4POadlWKBvaXRe1Lf1YVPNI1jCGXbbkQuDo,26021
|
107
|
+
jarvis_ai_assistant-0.2.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
108
|
+
jarvis_ai_assistant-0.2.1.dist-info/entry_points.txt,sha256=JXK_n-d9HZ_RLz959CvpK5-UPOCwssn5oAH8dAHuebA,1277
|
109
|
+
jarvis_ai_assistant-0.2.1.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
110
|
+
jarvis_ai_assistant-0.2.1.dist-info/RECORD,,
|
File without changes
|
{jarvis_ai_assistant-0.2.0.dist-info → jarvis_ai_assistant-0.2.1.dist-info}/entry_points.txt
RENAMED
File without changes
|
{jarvis_ai_assistant-0.2.0.dist-info → jarvis_ai_assistant-0.2.1.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
File without changes
|