jarvis-ai-assistant 0.1.8__tar.gz → 0.1.10__tar.gz
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_ai_assistant-0.1.8/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.10}/PKG-INFO +1 -5
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/pyproject.toml +1 -5
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/setup.py +1 -5
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/__init__.py +1 -1
- jarvis_ai_assistant-0.1.10/src/jarvis/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.10/src/jarvis/__pycache__/agent.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.10/src/jarvis/__pycache__/main.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/__pycache__/zte_llm.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/agent.py +72 -76
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/main.py +8 -87
- jarvis_ai_assistant-0.1.10/src/jarvis/models/__init__.py +11 -0
- jarvis_ai_assistant-0.1.10/src/jarvis/models/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.10/src/jarvis/models/__pycache__/base.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.10/src/jarvis/models/__pycache__/kimi.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.10/src/jarvis/models/base.py +15 -0
- jarvis_ai_assistant-0.1.10/src/jarvis/models/kimi.py +135 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/__init__.py +0 -4
- jarvis_ai_assistant-0.1.10/src/jarvis/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/__pycache__/base.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.10/src/jarvis/tools/__pycache__/bing_search.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.10/src/jarvis/tools/__pycache__/search.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/__pycache__/sub_agent.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/base.py +0 -6
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10/src/jarvis_ai_assistant.egg-info}/PKG-INFO +1 -5
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis_ai_assistant.egg-info/SOURCES.txt +6 -5
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis_ai_assistant.egg-info/requires.txt +0 -4
- jarvis_ai_assistant-0.1.8/src/jarvis/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.8/src/jarvis/__pycache__/agent.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.8/src/jarvis/__pycache__/main.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.8/src/jarvis/models.py +0 -122
- jarvis_ai_assistant-0.1.8/src/jarvis/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.8/src/jarvis/tools/__pycache__/bing_search.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.8/src/jarvis/tools/__pycache__/search.cpython-313.pyc +0 -0
- jarvis_ai_assistant-0.1.8/src/jarvis/tools/search.py +0 -144
- jarvis_ai_assistant-0.1.8/src/jarvis/tools/sub_agent.py +0 -83
- jarvis_ai_assistant-0.1.8/src/jarvis/tools/webpage.py +0 -76
- jarvis_ai_assistant-0.1.8/src/jarvis/zte_llm.py +0 -135
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/MANIFEST.in +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/README.md +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/setup.cfg +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/__pycache__/models.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/__pycache__/tools.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/__pycache__/utils.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/__pycache__/file_ops.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/__pycache__/python_script.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/__pycache__/rag.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/__pycache__/shell.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/__pycache__/user_confirmation.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/__pycache__/user_input.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/__pycache__/user_interaction.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/__pycache__/webpage.cpython-313.pyc +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/file_ops.py +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/tools/shell.py +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis/utils.py +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis_ai_assistant.egg-info/dependency_links.txt +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis_ai_assistant.egg-info/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10}/src/jarvis_ai_assistant.egg-info/top_level.txt +0 -0
{jarvis_ai_assistant-0.1.8/src/jarvis_ai_assistant.egg-info → jarvis_ai_assistant-0.1.10}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: jarvis-ai-assistant
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
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
|
|
@@ -17,12 +17,8 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
17
17
|
Requires-Python: >=3.8
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
Requires-Dist: requests>=2.25.1
|
|
20
|
-
Requires-Dist: beautifulsoup4>=4.9.3
|
|
21
|
-
Requires-Dist: duckduckgo-search>=3.0.0
|
|
22
20
|
Requires-Dist: pyyaml>=5.1
|
|
23
|
-
Requires-Dist: ollama>=0.1.6
|
|
24
21
|
Requires-Dist: colorama>=0.4.6
|
|
25
|
-
Requires-Dist: openai>=1.2.0
|
|
26
22
|
Provides-Extra: dev
|
|
27
23
|
Requires-Dist: pytest; extra == "dev"
|
|
28
24
|
Requires-Dist: black; extra == "dev"
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "jarvis-ai-assistant"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.10"
|
|
8
8
|
description = "Jarvis: An AI assistant that uses tools to interact with the system"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Your Name", email = "your.email@example.com" }]
|
|
@@ -21,12 +21,8 @@ classifiers = [
|
|
|
21
21
|
keywords = ["jarvis", "ai", "assistant", "tools", "automation"]
|
|
22
22
|
dependencies = [
|
|
23
23
|
"requests>=2.25.1",
|
|
24
|
-
"beautifulsoup4>=4.9.3",
|
|
25
|
-
"duckduckgo-search>=3.0.0",
|
|
26
24
|
"pyyaml>=5.1",
|
|
27
|
-
"ollama>=0.1.6",
|
|
28
25
|
"colorama>=0.4.6",
|
|
29
|
-
"openai>=1.2.0",
|
|
30
26
|
]
|
|
31
27
|
requires-python = ">=3.8"
|
|
32
28
|
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="jarvis-ai-assistant",
|
|
5
|
-
version="0.1.
|
|
5
|
+
version="0.1.10",
|
|
6
6
|
author="skyfire",
|
|
7
7
|
author_email="skyfireitdiy@hotmail.com",
|
|
8
8
|
description="An AI assistant that uses various tools to interact with the system",
|
|
@@ -14,12 +14,8 @@ setup(
|
|
|
14
14
|
include_package_data=True,
|
|
15
15
|
install_requires=[
|
|
16
16
|
"requests>=2.25.1",
|
|
17
|
-
"beautifulsoup4>=4.9.3",
|
|
18
|
-
"duckduckgo-search>=3.0.0",
|
|
19
17
|
"pyyaml>=5.1",
|
|
20
|
-
"ollama>=0.1.6",
|
|
21
18
|
"colorama>=0.4.6",
|
|
22
|
-
"openai>=1.2.0",
|
|
23
19
|
],
|
|
24
20
|
entry_points={
|
|
25
21
|
"console_scripts": [
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -24,8 +24,69 @@ class Agent:
|
|
|
24
24
|
self.tool_registry = tool_registry or ToolRegistry(model)
|
|
25
25
|
self.name = name
|
|
26
26
|
self.is_sub_agent = is_sub_agent
|
|
27
|
+
self.messages = []
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@staticmethod
|
|
31
|
+
def extract_tool_calls(content: str) -> List[Dict]:
|
|
32
|
+
"""从内容中提取工具调用,如果检测到多个工具调用则抛出异常,并返回工具调用之前的内容和工具调用"""
|
|
33
|
+
# 分割内容为行
|
|
34
|
+
lines = content.split('\n')
|
|
35
|
+
tool_call_lines = []
|
|
36
|
+
in_tool_call = False
|
|
37
|
+
|
|
38
|
+
# 逐行处理
|
|
39
|
+
for line in lines:
|
|
40
|
+
if '<START_TOOL_CALL>' in line:
|
|
41
|
+
in_tool_call = True
|
|
42
|
+
continue
|
|
43
|
+
elif '<END_TOOL_CALL>' in line:
|
|
44
|
+
if in_tool_call and tool_call_lines:
|
|
45
|
+
try:
|
|
46
|
+
# 直接解析YAML
|
|
47
|
+
tool_call_text = '\n'.join(tool_call_lines)
|
|
48
|
+
tool_call_data = yaml.safe_load(tool_call_text)
|
|
49
|
+
|
|
50
|
+
# 验证必要的字段
|
|
51
|
+
if "name" in tool_call_data and "arguments" in tool_call_data:
|
|
52
|
+
# 返回工具调用之前的内容和工具调用
|
|
53
|
+
return [{
|
|
54
|
+
"name": tool_call_data["name"],
|
|
55
|
+
"arguments": tool_call_data["arguments"]
|
|
56
|
+
}]
|
|
57
|
+
else:
|
|
58
|
+
PrettyOutput.print("工具调用缺少必要字段", OutputType.ERROR)
|
|
59
|
+
raise '工具调用缺少必要字段'
|
|
60
|
+
except yaml.YAMLError as e:
|
|
61
|
+
PrettyOutput.print(f"YAML解析错误: {str(e)}", OutputType.ERROR)
|
|
62
|
+
raise 'YAML解析错误'
|
|
63
|
+
except Exception as e:
|
|
64
|
+
PrettyOutput.print(f"处理工具调用时发生错误: {str(e)}", OutputType.ERROR)
|
|
65
|
+
raise '处理工具调用时发生错误'
|
|
66
|
+
in_tool_call = False
|
|
67
|
+
continue
|
|
68
|
+
|
|
69
|
+
if in_tool_call:
|
|
70
|
+
tool_call_lines.append(line)
|
|
71
|
+
|
|
72
|
+
return []
|
|
73
|
+
|
|
74
|
+
def _call_model(self, messages: List[Dict]) -> Dict:
|
|
75
|
+
"""调用模型获取响应"""
|
|
76
|
+
try:
|
|
77
|
+
return self.model.chat(
|
|
78
|
+
messages=messages,
|
|
79
|
+
)
|
|
80
|
+
except Exception as e:
|
|
81
|
+
raise Exception(f"{self.name}: 模型调用失败: {str(e)}")
|
|
82
|
+
|
|
83
|
+
def run(self, user_input: str) -> str:
|
|
84
|
+
"""处理用户输入并返回响应,返回任务总结报告"""
|
|
85
|
+
self.clear_history()
|
|
86
|
+
|
|
87
|
+
# 显示任务开始
|
|
88
|
+
PrettyOutput.section(f"开始新任务: {self.name}", OutputType.PLANNING)
|
|
27
89
|
|
|
28
|
-
# 构建工具说明
|
|
29
90
|
tools_prompt = "可用工具:\n"
|
|
30
91
|
for tool in self.tool_registry.get_all_tools():
|
|
31
92
|
tools_prompt += f"- 名称: {tool['name']}\n"
|
|
@@ -34,8 +95,8 @@ class Agent:
|
|
|
34
95
|
|
|
35
96
|
self.messages = [
|
|
36
97
|
{
|
|
37
|
-
"role": "
|
|
38
|
-
"content": f"""你是 {name},一个严格遵循 ReAct 框架进行逐步推理和行动的 AI 助手。
|
|
98
|
+
"role": "user",
|
|
99
|
+
"content": f"""你是 {self.name},一个严格遵循 ReAct 框架进行逐步推理和行动的 AI 助手。
|
|
39
100
|
|
|
40
101
|
{tools_prompt}
|
|
41
102
|
|
|
@@ -125,78 +186,12 @@ arguments:
|
|
|
125
186
|
- 不要虚构对话
|
|
126
187
|
- 每个动作后停止
|
|
127
188
|
- 只在有实际用户输入时继续
|
|
189
|
+
|
|
190
|
+
任务:
|
|
191
|
+
{user_input}
|
|
128
192
|
"""
|
|
129
193
|
}
|
|
130
194
|
]
|
|
131
|
-
|
|
132
|
-
@staticmethod
|
|
133
|
-
def extract_tool_calls(content: str) -> Tuple[str, List[Dict]]:
|
|
134
|
-
"""从内容中提取工具调用,如果检测到多个工具调用则抛出异常,并返回工具调用之前的内容和工具调用"""
|
|
135
|
-
# 分割内容为行
|
|
136
|
-
lines = content.split('\n')
|
|
137
|
-
tool_call_lines = []
|
|
138
|
-
content_lines = [] # 存储工具调用之前的内容
|
|
139
|
-
in_tool_call = False
|
|
140
|
-
|
|
141
|
-
# 逐行处理
|
|
142
|
-
for line in lines:
|
|
143
|
-
content_lines.append(line) # 所有内容都添加到 content_lines
|
|
144
|
-
|
|
145
|
-
if '<START_TOOL_CALL>' in line:
|
|
146
|
-
in_tool_call = True
|
|
147
|
-
continue
|
|
148
|
-
elif '<END_TOOL_CALL>' in line:
|
|
149
|
-
if in_tool_call and tool_call_lines:
|
|
150
|
-
try:
|
|
151
|
-
# 直接解析YAML
|
|
152
|
-
tool_call_text = '\n'.join(tool_call_lines)
|
|
153
|
-
tool_call_data = yaml.safe_load(tool_call_text)
|
|
154
|
-
|
|
155
|
-
# 验证必要的字段
|
|
156
|
-
if "name" in tool_call_data and "arguments" in tool_call_data:
|
|
157
|
-
# 返回工具调用之前的内容和工具调用
|
|
158
|
-
return '\n'.join(content_lines), [{
|
|
159
|
-
"name": tool_call_data["name"],
|
|
160
|
-
"arguments": tool_call_data["arguments"]
|
|
161
|
-
}]
|
|
162
|
-
else:
|
|
163
|
-
PrettyOutput.print("工具调用缺少必要字段", OutputType.ERROR)
|
|
164
|
-
raise '工具调用缺少必要字段'
|
|
165
|
-
except yaml.YAMLError as e:
|
|
166
|
-
PrettyOutput.print(f"YAML解析错误: {str(e)}", OutputType.ERROR)
|
|
167
|
-
raise 'YAML解析错误'
|
|
168
|
-
except Exception as e:
|
|
169
|
-
PrettyOutput.print(f"处理工具调用时发生错误: {str(e)}", OutputType.ERROR)
|
|
170
|
-
raise '处理工具调用时发生错误'
|
|
171
|
-
in_tool_call = False
|
|
172
|
-
continue
|
|
173
|
-
|
|
174
|
-
if in_tool_call:
|
|
175
|
-
tool_call_lines.append(line)
|
|
176
|
-
|
|
177
|
-
# 如果没有找到有效的工具调用,返回原始内容
|
|
178
|
-
return '\n'.join(content_lines), []
|
|
179
|
-
|
|
180
|
-
def _call_model(self, messages: List[Dict]) -> Dict:
|
|
181
|
-
"""调用模型获取响应"""
|
|
182
|
-
try:
|
|
183
|
-
return self.model.chat(
|
|
184
|
-
messages=messages,
|
|
185
|
-
)
|
|
186
|
-
except Exception as e:
|
|
187
|
-
raise Exception(f"{self.name}: 模型调用失败: {str(e)}")
|
|
188
|
-
|
|
189
|
-
def run(self, user_input: str) -> str:
|
|
190
|
-
"""处理用户输入并返回响应,返回任务总结报告"""
|
|
191
|
-
self.clear_history()
|
|
192
|
-
|
|
193
|
-
# 显示任务开始
|
|
194
|
-
PrettyOutput.section(f"开始新任务: {self.name}", OutputType.PLANNING)
|
|
195
|
-
|
|
196
|
-
self.messages.append({
|
|
197
|
-
"role": "user",
|
|
198
|
-
"content": user_input
|
|
199
|
-
})
|
|
200
195
|
|
|
201
196
|
while True:
|
|
202
197
|
try:
|
|
@@ -218,15 +213,15 @@ arguments:
|
|
|
218
213
|
|
|
219
214
|
self.messages.append({
|
|
220
215
|
"role": "assistant",
|
|
221
|
-
"content":
|
|
216
|
+
"content": current_response
|
|
222
217
|
})
|
|
223
218
|
|
|
224
219
|
|
|
225
|
-
if len(result
|
|
220
|
+
if len(result) > 0:
|
|
226
221
|
try:
|
|
227
222
|
# 显示工具调用
|
|
228
223
|
PrettyOutput.print("执行工具调用...", OutputType.PROGRESS)
|
|
229
|
-
tool_result = self.tool_registry.handle_tool_calls(result
|
|
224
|
+
tool_result = self.tool_registry.handle_tool_calls(result)
|
|
230
225
|
PrettyOutput.print(tool_result, OutputType.RESULT)
|
|
231
226
|
except Exception as e:
|
|
232
227
|
PrettyOutput.print(str(e), OutputType.ERROR)
|
|
@@ -295,4 +290,5 @@ arguments:
|
|
|
295
290
|
|
|
296
291
|
def clear_history(self):
|
|
297
292
|
"""清除对话历史,只保留系统提示"""
|
|
298
|
-
self.messages = [
|
|
293
|
+
self.messages = []
|
|
294
|
+
self.model.reset()
|
|
@@ -12,33 +12,9 @@ sys.path.insert(0, str(Path(__file__).parent.parent))
|
|
|
12
12
|
|
|
13
13
|
from jarvis.agent import Agent
|
|
14
14
|
from jarvis.tools import ToolRegistry
|
|
15
|
-
from jarvis.models import
|
|
15
|
+
from jarvis.models import KimiModel
|
|
16
16
|
from jarvis.utils import PrettyOutput, OutputType, get_multiline_input, load_env_from_file
|
|
17
|
-
from jarvis.zte_llm import create_zte_llm
|
|
18
17
|
|
|
19
|
-
# 定义支持的平台和模型
|
|
20
|
-
SUPPORTED_PLATFORMS = {
|
|
21
|
-
"ollama": {
|
|
22
|
-
"models": ["qwen2.5:14b", "qwq"],
|
|
23
|
-
"default": "qwen2.5:14b",
|
|
24
|
-
"allow_custom": True
|
|
25
|
-
},
|
|
26
|
-
"ddgs": {
|
|
27
|
-
"models": ["gpt-4o-mini", "claude-3-haiku", "llama-3.1-70b", "mixtral-8x7b"],
|
|
28
|
-
"default": "gpt-4o-mini",
|
|
29
|
-
"allow_custom": False
|
|
30
|
-
},
|
|
31
|
-
"zte": {
|
|
32
|
-
"models": ["NebulaBiz", "nebulacoder", "NTele-72B"],
|
|
33
|
-
"default": "NebulaBiz",
|
|
34
|
-
"allow_custom": False
|
|
35
|
-
},
|
|
36
|
-
"openai": {
|
|
37
|
-
"models": ["deepseek-chat"],
|
|
38
|
-
"default": "deepseek-chat",
|
|
39
|
-
"allow_custom": True
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
18
|
|
|
43
19
|
def load_tasks() -> dict:
|
|
44
20
|
"""Load tasks from .jarvis file if it exists."""
|
|
@@ -98,75 +74,20 @@ def main():
|
|
|
98
74
|
"""Main entry point for Jarvis."""
|
|
99
75
|
|
|
100
76
|
load_env_from_file()
|
|
101
|
-
|
|
102
|
-
parser = argparse.ArgumentParser(description="Jarvis AI Assistant")
|
|
103
|
-
|
|
104
|
-
# 添加平台选择参数
|
|
105
|
-
parser.add_argument(
|
|
106
|
-
"--platform",
|
|
107
|
-
choices=list(SUPPORTED_PLATFORMS.keys()),
|
|
108
|
-
default=os.getenv("JARVIS_PLATFORM") or "ddgs",
|
|
109
|
-
help="选择运行平台 (默认: ollama)"
|
|
110
|
-
)
|
|
111
|
-
|
|
112
|
-
# 添加模型选择参数
|
|
113
|
-
parser.add_argument(
|
|
114
|
-
"--model",
|
|
115
|
-
help="选择模型 (默认: 根据平台自动选择)"
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
# 添加API基础URL参数
|
|
119
|
-
parser.add_argument(
|
|
120
|
-
"--api-base",
|
|
121
|
-
default=os.getenv("JARVIS_OLLAMA_API_BASE") or "http://localhost:11434",
|
|
122
|
-
help="Ollama API基础URL (仅用于Ollama平台, 默认: http://localhost:11434)"
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
args = parser.parse_args()
|
|
126
|
-
|
|
127
|
-
args.model = args.model or os.getenv("JARVIS_MODEL")
|
|
128
77
|
|
|
129
|
-
# 修改模型验证逻辑
|
|
130
|
-
if args.model:
|
|
131
|
-
if (args.model not in SUPPORTED_PLATFORMS[args.platform]["models"] and
|
|
132
|
-
not SUPPORTED_PLATFORMS[args.platform]["allow_custom"]):
|
|
133
|
-
supported_models = ", ".join(SUPPORTED_PLATFORMS[args.platform]["models"])
|
|
134
|
-
PrettyOutput.print(
|
|
135
|
-
f"错误: 平台 {args.platform} 不支持模型 {args.model}\n"
|
|
136
|
-
f"支持的模型: {supported_models}",
|
|
137
|
-
OutputType.ERROR
|
|
138
|
-
)
|
|
139
|
-
return 1
|
|
140
|
-
else:
|
|
141
|
-
args.model = SUPPORTED_PLATFORMS[args.platform]["default"]
|
|
142
|
-
|
|
143
78
|
try:
|
|
144
|
-
|
|
145
|
-
if
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
platform_name = f"Ollama ({args.model})"
|
|
151
|
-
elif args.platform == "ddgs": # ddgs
|
|
152
|
-
model = DDGSModel(model_name=args.model)
|
|
153
|
-
platform_name = f"DuckDuckGo Search ({args.model})"
|
|
154
|
-
elif args.platform == "zte": # zte
|
|
155
|
-
model = create_zte_llm(model_name=args.model)
|
|
156
|
-
platform_name = f"ZTE ({args.model})"
|
|
157
|
-
elif args.platform == "openai":
|
|
158
|
-
model = OpenAIModel(
|
|
159
|
-
model_name=args.model,
|
|
160
|
-
api_key=os.getenv("OPENAI_API_KEY"),
|
|
161
|
-
api_base=os.getenv("OPENAI_API_BASE")
|
|
162
|
-
)
|
|
163
|
-
platform_name = f"OpenAI ({args.model})"
|
|
79
|
+
kimi_api_key = os.getenv("KIMI_API_KEY")
|
|
80
|
+
if not kimi_api_key:
|
|
81
|
+
PrettyOutput.print("Kimi API key 未设置", OutputType.ERROR)
|
|
82
|
+
return 1
|
|
83
|
+
|
|
84
|
+
model = KimiModel(kimi_api_key)
|
|
164
85
|
|
|
165
86
|
tool_registry = ToolRegistry(model)
|
|
166
87
|
agent = Agent(model, tool_registry)
|
|
167
88
|
|
|
168
89
|
# 欢迎信息
|
|
169
|
-
PrettyOutput.print(f"Jarvis 已初始化 -
|
|
90
|
+
PrettyOutput.print(f"Jarvis 已初始化 - With Kimi", OutputType.SYSTEM)
|
|
170
91
|
|
|
171
92
|
# 加载预定义任务
|
|
172
93
|
tasks = load_tasks()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
from typing import Dict, List, Optional, Tuple
|
|
2
|
+
from duckduckgo_search import DDGS
|
|
3
|
+
import ollama
|
|
4
|
+
import yaml
|
|
5
|
+
import openai
|
|
6
|
+
|
|
7
|
+
from ..utils import OutputType, PrettyOutput
|
|
8
|
+
from .base import BaseModel
|
|
9
|
+
from .kimi import KimiModel
|
|
10
|
+
|
|
11
|
+
__all__ = ['BaseModel', 'KimiModel']
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
from typing import Dict, List
|
|
2
|
+
import requests
|
|
3
|
+
import json
|
|
4
|
+
import os
|
|
5
|
+
from .base import BaseModel
|
|
6
|
+
from ..utils import PrettyOutput, OutputType
|
|
7
|
+
import time
|
|
8
|
+
|
|
9
|
+
class KimiModel(BaseModel):
|
|
10
|
+
"""Kimi模型实现"""
|
|
11
|
+
|
|
12
|
+
def __init__(self, api_key: str = None):
|
|
13
|
+
"""
|
|
14
|
+
初始化Kimi模型
|
|
15
|
+
Args:
|
|
16
|
+
api_key: Kimi API密钥,如果不提供则从环境变量获取
|
|
17
|
+
"""
|
|
18
|
+
self.api_key = api_key or os.getenv("KIMI_API_KEY")
|
|
19
|
+
if not self.api_key:
|
|
20
|
+
raise Exception("KIMI_API_KEY is not set")
|
|
21
|
+
self.auth_header = f"Bearer {self.api_key}"
|
|
22
|
+
self.chat_id = ""
|
|
23
|
+
|
|
24
|
+
def _create_chat(self) -> bool:
|
|
25
|
+
"""创建新的对话会话"""
|
|
26
|
+
url = "https://kimi.moonshot.cn/api/chat"
|
|
27
|
+
payload = json.dumps({
|
|
28
|
+
"name": "未命名会话",
|
|
29
|
+
"is_example": False,
|
|
30
|
+
"kimiplus_id": "kimi"
|
|
31
|
+
})
|
|
32
|
+
headers = {
|
|
33
|
+
'Authorization': self.auth_header,
|
|
34
|
+
'Content-Type': 'application/json'
|
|
35
|
+
}
|
|
36
|
+
try:
|
|
37
|
+
response = requests.request("POST", url, headers=headers, data=payload)
|
|
38
|
+
self.chat_id = response.json()["id"]
|
|
39
|
+
return True
|
|
40
|
+
except Exception as e:
|
|
41
|
+
PrettyOutput.print(f"Failed to create chat: {e}", OutputType.ERROR)
|
|
42
|
+
return False
|
|
43
|
+
|
|
44
|
+
def chat(self, messages: List[Dict]) -> str:
|
|
45
|
+
"""
|
|
46
|
+
实现BaseModel的chat方法
|
|
47
|
+
Args:
|
|
48
|
+
messages: 对话消息列表
|
|
49
|
+
Returns:
|
|
50
|
+
str: 模型的回复内容
|
|
51
|
+
"""
|
|
52
|
+
if not self.chat_id:
|
|
53
|
+
if not self._create_chat():
|
|
54
|
+
raise Exception("Failed to create chat")
|
|
55
|
+
|
|
56
|
+
url = f"https://kimi.moonshot.cn/api/chat/{self.chat_id}/completion/stream"
|
|
57
|
+
payload = json.dumps({
|
|
58
|
+
"messages": [messages[-1]],
|
|
59
|
+
"use_search": True,
|
|
60
|
+
"extend": {
|
|
61
|
+
"sidebar": True
|
|
62
|
+
},
|
|
63
|
+
"kimiplus_id": "kimi",
|
|
64
|
+
"use_research": False,
|
|
65
|
+
"use_math": False,
|
|
66
|
+
"refs": [],
|
|
67
|
+
"refs_file": []
|
|
68
|
+
})
|
|
69
|
+
headers = {
|
|
70
|
+
'Authorization': self.auth_header,
|
|
71
|
+
'Content-Type': 'application/json'
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
response = requests.request("POST", url, headers=headers, data=payload, stream=True)
|
|
76
|
+
full_response = ""
|
|
77
|
+
references = []
|
|
78
|
+
|
|
79
|
+
for line in response.iter_lines():
|
|
80
|
+
if not line:
|
|
81
|
+
continue
|
|
82
|
+
|
|
83
|
+
line = line.decode('utf-8')
|
|
84
|
+
if not line.startswith("data: "):
|
|
85
|
+
continue
|
|
86
|
+
|
|
87
|
+
try:
|
|
88
|
+
data = json.loads(line[6:]) # 去掉 "data: " 前缀
|
|
89
|
+
|
|
90
|
+
# 处理不同类型的事件
|
|
91
|
+
if data.get("event") == "cmpl":
|
|
92
|
+
if "text" in data:
|
|
93
|
+
text = data["text"]
|
|
94
|
+
PrettyOutput.print_stream(text, OutputType.SYSTEM) # 使用统一的流式输出
|
|
95
|
+
full_response += text
|
|
96
|
+
elif data.get("event") == "ref_docs":
|
|
97
|
+
if "ref_cards" in data:
|
|
98
|
+
for ref in data["ref_cards"]:
|
|
99
|
+
reference = {
|
|
100
|
+
"title": ref.get("title", ""),
|
|
101
|
+
"url": ref.get("url", ""),
|
|
102
|
+
"abstract": ref.get("abstract", "")
|
|
103
|
+
}
|
|
104
|
+
references.append(reference)
|
|
105
|
+
PrettyOutput.print(f"\n参考来源: {reference['title']} - {reference['url']}",
|
|
106
|
+
OutputType.INFO)
|
|
107
|
+
elif data.get("event") == "error":
|
|
108
|
+
error_msg = data.get("error", "Unknown error")
|
|
109
|
+
raise Exception(f"Chat error: {error_msg}")
|
|
110
|
+
elif data.get("event") == "all_done":
|
|
111
|
+
break
|
|
112
|
+
|
|
113
|
+
except json.JSONDecodeError:
|
|
114
|
+
continue
|
|
115
|
+
|
|
116
|
+
# 如果有参考文献,在回答后面添加引用信息
|
|
117
|
+
if references:
|
|
118
|
+
full_response += "\n\n参考来源:\n"
|
|
119
|
+
for i, ref in enumerate(references, 1):
|
|
120
|
+
full_response += f"{i}. {ref['title']} - {ref['url']}\n"
|
|
121
|
+
|
|
122
|
+
PrettyOutput.print_stream_end() # 结束流式输出
|
|
123
|
+
return full_response
|
|
124
|
+
|
|
125
|
+
except Exception as e:
|
|
126
|
+
raise Exception(f"Kimi API调用失败: {str(e)}")
|
|
127
|
+
|
|
128
|
+
def reset(self):
|
|
129
|
+
"""重置模型"""
|
|
130
|
+
self.chat_id = ""
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
if __name__ == "__main__":
|
|
134
|
+
kimi = KimiModel()
|
|
135
|
+
print(kimi.chat([{"role": "user", "content": "ollama如何部署"}]))
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
from .base import Tool, ToolRegistry
|
|
2
2
|
from .file_ops import FileOperationTool
|
|
3
|
-
from .search import SearchTool
|
|
4
3
|
from .shell import ShellTool
|
|
5
|
-
from .webpage import WebpageTool
|
|
6
4
|
|
|
7
5
|
__all__ = [
|
|
8
6
|
'Tool',
|
|
9
7
|
'ToolRegistry',
|
|
10
8
|
'FileOperationTool',
|
|
11
|
-
'SearchTool',
|
|
12
9
|
'ShellTool',
|
|
13
|
-
'WebpageTool',
|
|
14
10
|
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -30,18 +30,12 @@ class ToolRegistry:
|
|
|
30
30
|
|
|
31
31
|
def _register_default_tools(self):
|
|
32
32
|
"""注册所有默认工具"""
|
|
33
|
-
from .search import SearchTool
|
|
34
33
|
from .shell import ShellTool
|
|
35
34
|
from .file_ops import FileOperationTool
|
|
36
|
-
from .webpage import WebpageTool
|
|
37
|
-
from .sub_agent import SubAgentTool
|
|
38
35
|
|
|
39
36
|
tools = [
|
|
40
|
-
SearchTool(self.model),
|
|
41
37
|
ShellTool(),
|
|
42
38
|
FileOperationTool(),
|
|
43
|
-
WebpageTool(),
|
|
44
|
-
SubAgentTool(self.model)
|
|
45
39
|
]
|
|
46
40
|
|
|
47
41
|
for tool in tools:
|
{jarvis_ai_assistant-0.1.8 → jarvis_ai_assistant-0.1.10/src/jarvis_ai_assistant.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: jarvis-ai-assistant
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.10
|
|
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
|
|
@@ -17,12 +17,8 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
17
17
|
Requires-Python: >=3.8
|
|
18
18
|
Description-Content-Type: text/markdown
|
|
19
19
|
Requires-Dist: requests>=2.25.1
|
|
20
|
-
Requires-Dist: beautifulsoup4>=4.9.3
|
|
21
|
-
Requires-Dist: duckduckgo-search>=3.0.0
|
|
22
20
|
Requires-Dist: pyyaml>=5.1
|
|
23
|
-
Requires-Dist: ollama>=0.1.6
|
|
24
21
|
Requires-Dist: colorama>=0.4.6
|
|
25
|
-
Requires-Dist: openai>=1.2.0
|
|
26
22
|
Provides-Extra: dev
|
|
27
23
|
Requires-Dist: pytest; extra == "dev"
|
|
28
24
|
Requires-Dist: black; extra == "dev"
|
|
@@ -5,9 +5,7 @@ setup.py
|
|
|
5
5
|
src/jarvis/__init__.py
|
|
6
6
|
src/jarvis/agent.py
|
|
7
7
|
src/jarvis/main.py
|
|
8
|
-
src/jarvis/models.py
|
|
9
8
|
src/jarvis/utils.py
|
|
10
|
-
src/jarvis/zte_llm.py
|
|
11
9
|
src/jarvis/__pycache__/__init__.cpython-313.pyc
|
|
12
10
|
src/jarvis/__pycache__/agent.cpython-313.pyc
|
|
13
11
|
src/jarvis/__pycache__/main.cpython-313.pyc
|
|
@@ -15,13 +13,16 @@ src/jarvis/__pycache__/models.cpython-313.pyc
|
|
|
15
13
|
src/jarvis/__pycache__/tools.cpython-313.pyc
|
|
16
14
|
src/jarvis/__pycache__/utils.cpython-313.pyc
|
|
17
15
|
src/jarvis/__pycache__/zte_llm.cpython-313.pyc
|
|
16
|
+
src/jarvis/models/__init__.py
|
|
17
|
+
src/jarvis/models/base.py
|
|
18
|
+
src/jarvis/models/kimi.py
|
|
19
|
+
src/jarvis/models/__pycache__/__init__.cpython-313.pyc
|
|
20
|
+
src/jarvis/models/__pycache__/base.cpython-313.pyc
|
|
21
|
+
src/jarvis/models/__pycache__/kimi.cpython-313.pyc
|
|
18
22
|
src/jarvis/tools/__init__.py
|
|
19
23
|
src/jarvis/tools/base.py
|
|
20
24
|
src/jarvis/tools/file_ops.py
|
|
21
|
-
src/jarvis/tools/search.py
|
|
22
25
|
src/jarvis/tools/shell.py
|
|
23
|
-
src/jarvis/tools/sub_agent.py
|
|
24
|
-
src/jarvis/tools/webpage.py
|
|
25
26
|
src/jarvis/tools/__pycache__/__init__.cpython-313.pyc
|
|
26
27
|
src/jarvis/tools/__pycache__/base.cpython-313.pyc
|
|
27
28
|
src/jarvis/tools/__pycache__/bing_search.cpython-313.pyc
|