jarvis-ai-assistant 0.1.32__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- jarvis/__init__.py +3 -0
- jarvis/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/__pycache__/agent.cpython-313.pyc +0 -0
- jarvis/__pycache__/main.cpython-313.pyc +0 -0
- jarvis/__pycache__/models.cpython-313.pyc +0 -0
- jarvis/__pycache__/tools.cpython-313.pyc +0 -0
- jarvis/__pycache__/utils.cpython-313.pyc +0 -0
- jarvis/__pycache__/zte_llm.cpython-313.pyc +0 -0
- jarvis/agent.py +289 -0
- jarvis/main.py +148 -0
- jarvis/models/__init__.py +3 -0
- jarvis/models/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/base.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/kimi.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/openai.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/oyi.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/registry.cpython-313.pyc +0 -0
- jarvis/models/base.py +39 -0
- jarvis/models/kimi.py +389 -0
- jarvis/models/openai.py +96 -0
- jarvis/models/oyi.py +271 -0
- jarvis/models/registry.py +199 -0
- jarvis/tools/__init__.py +5 -0
- jarvis/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/base.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/bing_search.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/calculator.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/calculator_tool.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/file_ops.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/generator.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/methodology.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/python_script.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/rag.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/registry.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/search.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/shell.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/sub_agent.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/user_confirmation.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/user_input.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/user_interaction.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/webpage.cpython-313.pyc +0 -0
- jarvis/tools/base.py +23 -0
- jarvis/tools/file_ops.py +110 -0
- jarvis/tools/generator.py +172 -0
- jarvis/tools/methodology.py +145 -0
- jarvis/tools/registry.py +183 -0
- jarvis/tools/shell.py +78 -0
- jarvis/tools/sub_agent.py +82 -0
- jarvis/utils.py +202 -0
- jarvis_ai_assistant-0.1.32.dist-info/LICENSE +21 -0
- jarvis_ai_assistant-0.1.32.dist-info/METADATA +345 -0
- jarvis_ai_assistant-0.1.32.dist-info/RECORD +55 -0
- jarvis_ai_assistant-0.1.32.dist-info/WHEEL +5 -0
- jarvis_ai_assistant-0.1.32.dist-info/entry_points.txt +2 -0
- jarvis_ai_assistant-0.1.32.dist-info/top_level.txt +1 -0
jarvis/__init__.py
ADDED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
jarvis/agent.py
ADDED
@@ -0,0 +1,289 @@
|
|
1
|
+
import time
|
2
|
+
from typing import Dict, List, Optional
|
3
|
+
|
4
|
+
import yaml
|
5
|
+
|
6
|
+
from .models.registry import ModelRegistry
|
7
|
+
from .tools import ToolRegistry
|
8
|
+
from .utils import PrettyOutput, OutputType, get_multiline_input, while_success
|
9
|
+
import os
|
10
|
+
from datetime import datetime
|
11
|
+
from prompt_toolkit import prompt
|
12
|
+
|
13
|
+
class Agent:
|
14
|
+
def __init__(self, name: str = "Jarvis", is_sub_agent: bool = False):
|
15
|
+
"""Initialize Agent with a model, optional tool registry and name
|
16
|
+
|
17
|
+
Args:
|
18
|
+
model: 语言模型实例
|
19
|
+
tool_registry: 工具注册表实例
|
20
|
+
name: Agent名称,默认为"Jarvis"
|
21
|
+
is_sub_agent: 是否为子Agent,默认为False
|
22
|
+
"""
|
23
|
+
self.model = ModelRegistry.get_global_model()
|
24
|
+
self.tool_registry = ToolRegistry.get_global_tool_registry()
|
25
|
+
self.name = name
|
26
|
+
self.is_sub_agent = is_sub_agent
|
27
|
+
self.prompt = ""
|
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 Exception("工具调用缺少必要字段")
|
60
|
+
except yaml.YAMLError as e:
|
61
|
+
PrettyOutput.print(f"YAML解析错误: {str(e)}", OutputType.ERROR)
|
62
|
+
raise Exception(f"YAML解析错误: {str(e)}")
|
63
|
+
except Exception as e:
|
64
|
+
PrettyOutput.print(f"处理工具调用时发生错误: {str(e)}", OutputType.ERROR)
|
65
|
+
raise Exception(f"处理工具调用时发生错误: {str(e)}")
|
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, message: str) -> str:
|
75
|
+
"""调用模型获取响应"""
|
76
|
+
sleep_time = 5
|
77
|
+
while True:
|
78
|
+
ret = while_success(lambda: self.model.chat(message), sleep_time=5)
|
79
|
+
if ret:
|
80
|
+
return ret
|
81
|
+
else:
|
82
|
+
PrettyOutput.print(f"调用模型失败,重试中... 等待 {sleep_time}s", OutputType.INFO)
|
83
|
+
time.sleep(sleep_time)
|
84
|
+
sleep_time *= 2
|
85
|
+
if sleep_time > 30:
|
86
|
+
sleep_time = 30
|
87
|
+
continue
|
88
|
+
|
89
|
+
|
90
|
+
def _load_methodology(self) -> str:
|
91
|
+
"""加载方法论"""
|
92
|
+
user_jarvis_methodology = os.path.expanduser("~/.jarvis_methodology")
|
93
|
+
ret = ""
|
94
|
+
if os.path.exists(user_jarvis_methodology):
|
95
|
+
with open(user_jarvis_methodology, "r", encoding="utf-8") as f:
|
96
|
+
data = yaml.safe_load(f)
|
97
|
+
for k, v in data.items():
|
98
|
+
ret += f"问题类型: \n{k}\n方法论: \n{v}\n\n"
|
99
|
+
return ret
|
100
|
+
|
101
|
+
def run(self, user_input: str, file_list: Optional[List[str]] = None, keep_history: bool = False) -> str:
|
102
|
+
"""处理用户输入并返回响应,返回任务总结报告
|
103
|
+
|
104
|
+
Args:
|
105
|
+
user_input: 用户输入的任务描述
|
106
|
+
file_list: 可选的文件列表,默认为None
|
107
|
+
keep_history: 是否保留对话历史,默认为False
|
108
|
+
|
109
|
+
Returns:
|
110
|
+
str: 任务总结报告
|
111
|
+
"""
|
112
|
+
try:
|
113
|
+
self.clear_history()
|
114
|
+
|
115
|
+
if file_list:
|
116
|
+
self.model.upload_files(file_list)
|
117
|
+
|
118
|
+
# 加载方法论
|
119
|
+
methodology = self._load_methodology()
|
120
|
+
|
121
|
+
methodology_prompt = ""
|
122
|
+
if methodology:
|
123
|
+
methodology_prompt = f"""这是以往处理问题的标准方法论,如果当前任务与此类似,可参考:
|
124
|
+
{methodology}
|
125
|
+
|
126
|
+
"""
|
127
|
+
|
128
|
+
# 显示任务开始
|
129
|
+
PrettyOutput.section(f"开始新任务: {self.name}", OutputType.PLANNING)
|
130
|
+
|
131
|
+
tools_prompt = "可用工具:\n"
|
132
|
+
for tool in self.tool_registry.get_all_tools():
|
133
|
+
tools_prompt += f"- 名称: {tool['name']}\n"
|
134
|
+
tools_prompt += f" 描述: {tool['description']}\n"
|
135
|
+
tools_prompt += f" 参数: {tool['parameters']}\n"
|
136
|
+
|
137
|
+
self.model.set_system_message(f"""你是 {self.name},一个问题处理能力强大的 AI 助手。
|
138
|
+
|
139
|
+
你会严格按照以下步骤处理问题:
|
140
|
+
1. 问题重述:确认理解问题
|
141
|
+
2. 根因分析(如果是问题分析类需要,其他不需要)
|
142
|
+
3. 设定目标:需要可达成,可检验的一个或多个目标
|
143
|
+
4. 生成解决方案:生成一个或者多个具备可操作性的解决方案
|
144
|
+
5. 评估解决方案:从众多解决方案中选择一种最优的方案
|
145
|
+
6. 制定行动计划:根据目前可以使用的工具制定行动计划
|
146
|
+
7. 执行行动计划:每步执行一个步骤,最多使用一个工具(工具执行完成后,等待工具结果再执行下一步)
|
147
|
+
8. 监控与调整:如果执行结果与预期不符,则反思并调整行动计划,迭代之前的步骤
|
148
|
+
9. 更新方法论(如有必要):任务完成后总结执行过程中的经验教训,生成同类问题的通用方法论,使用方法论工具进行更新或者添加
|
149
|
+
|
150
|
+
-------------------------------------------------------------
|
151
|
+
|
152
|
+
方法论模板:
|
153
|
+
1. 问题重述
|
154
|
+
2. 最优解决方案
|
155
|
+
3. 最优方案执行步骤(失败的行动不需要体现)
|
156
|
+
|
157
|
+
-------------------------------------------------------------
|
158
|
+
|
159
|
+
{tools_prompt}
|
160
|
+
|
161
|
+
-------------------------------------------------------------
|
162
|
+
|
163
|
+
工具使用格式:
|
164
|
+
|
165
|
+
<START_TOOL_CALL>
|
166
|
+
name: tool_name
|
167
|
+
arguments:
|
168
|
+
param1: value1
|
169
|
+
param2: value2
|
170
|
+
<END_TOOL_CALL>
|
171
|
+
|
172
|
+
-------------------------------------------------------------
|
173
|
+
|
174
|
+
严格规则:
|
175
|
+
1. 每次只能执行一个工具
|
176
|
+
2. 等待用户提供执行结果
|
177
|
+
3. 不要假设或想象结果
|
178
|
+
4. 不要创建虚假对话
|
179
|
+
5. 如果现有信息不足以解决问题,则可以询问用户
|
180
|
+
6. 处理问题的每个步骤不是必须有的,可按情况省略
|
181
|
+
|
182
|
+
-------------------------------------------------------------
|
183
|
+
|
184
|
+
{methodology_prompt}
|
185
|
+
|
186
|
+
-------------------------------------------------------------
|
187
|
+
|
188
|
+
""")
|
189
|
+
self.prompt = f"用户任务: {user_input}"
|
190
|
+
|
191
|
+
while True:
|
192
|
+
try:
|
193
|
+
# 显示思考状态
|
194
|
+
PrettyOutput.print("分析任务...", OutputType.PROGRESS)
|
195
|
+
|
196
|
+
current_response = self._call_model(self.prompt)
|
197
|
+
|
198
|
+
try:
|
199
|
+
result = Agent.extract_tool_calls(current_response)
|
200
|
+
except Exception as e:
|
201
|
+
PrettyOutput.print(f"工具调用错误: {str(e)}", OutputType.ERROR)
|
202
|
+
self.prompt = f"工具调用错误: {str(e)}"
|
203
|
+
continue
|
204
|
+
|
205
|
+
if len(result) > 0:
|
206
|
+
|
207
|
+
PrettyOutput.print("执行工具调用...", OutputType.PROGRESS)
|
208
|
+
tool_result = self.tool_registry.handle_tool_calls(result)
|
209
|
+
PrettyOutput.print(tool_result, OutputType.RESULT)
|
210
|
+
|
211
|
+
self.prompt = tool_result
|
212
|
+
continue
|
213
|
+
|
214
|
+
# 获取用户输入
|
215
|
+
user_input = get_multiline_input(f"{self.name}: 您可以继续输入,或输入空行结束当前任务")
|
216
|
+
if user_input == "__interrupt__":
|
217
|
+
PrettyOutput.print("任务已取消", OutputType.WARNING)
|
218
|
+
return "Task cancelled by user"
|
219
|
+
|
220
|
+
if user_input:
|
221
|
+
self.prompt = user_input
|
222
|
+
continue
|
223
|
+
|
224
|
+
if not user_input:
|
225
|
+
while True:
|
226
|
+
choice = prompt("是否需要为此任务生成方法论以提升Jarvis对类似任务的处理能力?(y/n), 回车跳过: ")
|
227
|
+
if choice == "y":
|
228
|
+
self._make_methodology()
|
229
|
+
break
|
230
|
+
elif choice == "n" or choice == "":
|
231
|
+
break
|
232
|
+
else:
|
233
|
+
PrettyOutput.print("请输入y或n", OutputType.ERROR)
|
234
|
+
continue
|
235
|
+
PrettyOutput.section("任务完成", OutputType.SUCCESS)
|
236
|
+
if self.is_sub_agent:
|
237
|
+
# 生成任务总结
|
238
|
+
summary_prompt = f"""请对以上任务执行情况生成一个简洁的总结报告,包括:
|
239
|
+
|
240
|
+
1. 任务目标: 任务重述
|
241
|
+
2. 执行结果: 成功/失败
|
242
|
+
3. 关键信息: 提取执行过程中的重要信息
|
243
|
+
4. 重要发现: 任何值得注意的发现
|
244
|
+
5. 后续建议: 如果有的话
|
245
|
+
|
246
|
+
请用简洁的要点形式描述,突出重要信息。
|
247
|
+
"""
|
248
|
+
self.prompt = summary_prompt
|
249
|
+
summary = self._call_model(self.prompt)
|
250
|
+
return summary
|
251
|
+
else:
|
252
|
+
return "Task completed"
|
253
|
+
|
254
|
+
except Exception as e:
|
255
|
+
PrettyOutput.print(str(e), OutputType.ERROR)
|
256
|
+
return f"Task failed: {str(e)}"
|
257
|
+
|
258
|
+
except Exception as e:
|
259
|
+
PrettyOutput.print(str(e), OutputType.ERROR)
|
260
|
+
return f"Task failed: {str(e)}"
|
261
|
+
|
262
|
+
finally:
|
263
|
+
# 只在不保留历史时删除会话
|
264
|
+
if not keep_history:
|
265
|
+
try:
|
266
|
+
self.model.delete_chat()
|
267
|
+
except Exception as e:
|
268
|
+
PrettyOutput.print(f"清理会话时发生错误: {str(e)}", OutputType.ERROR)
|
269
|
+
|
270
|
+
def clear_history(self):
|
271
|
+
"""清除对话历史,只保留系统提示"""
|
272
|
+
self.prompt = ""
|
273
|
+
self.model.reset()
|
274
|
+
|
275
|
+
def _make_methodology(self):
|
276
|
+
"""生成方法论"""
|
277
|
+
current_response = self._call_model("""请根据之前的对话内容,判断是否有必要更新、添加、删除现有方法论,如果有,使用methodology工具进行管理。
|
278
|
+
方法论模板:
|
279
|
+
1. 问题重述
|
280
|
+
2. 最优解决方案
|
281
|
+
3. 最优方案执行步骤(失败的行动不需要体现)
|
282
|
+
""")
|
283
|
+
|
284
|
+
try:
|
285
|
+
result = Agent.extract_tool_calls(current_response)
|
286
|
+
except Exception as e:
|
287
|
+
PrettyOutput.print(f"工具调用错误: {str(e)}", OutputType.ERROR)
|
288
|
+
return
|
289
|
+
|
jarvis/main.py
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
"""Command line interface for Jarvis."""
|
3
|
+
|
4
|
+
import argparse
|
5
|
+
import yaml
|
6
|
+
import os
|
7
|
+
import sys
|
8
|
+
from pathlib import Path
|
9
|
+
from prompt_toolkit import prompt
|
10
|
+
|
11
|
+
from jarvis.models.registry import ModelRegistry
|
12
|
+
|
13
|
+
# 添加父目录到Python路径以支持导入
|
14
|
+
sys.path.insert(0, str(Path(__file__).parent.parent))
|
15
|
+
|
16
|
+
from jarvis.agent import Agent
|
17
|
+
from jarvis.tools import ToolRegistry
|
18
|
+
from jarvis.utils import PrettyOutput, OutputType, get_multiline_input, load_env_from_file
|
19
|
+
|
20
|
+
|
21
|
+
def load_tasks() -> dict:
|
22
|
+
"""Load tasks from .jarvis files in user home and current directory."""
|
23
|
+
tasks = {}
|
24
|
+
|
25
|
+
# 检查用户目录下的 .jarvis
|
26
|
+
user_jarvis = os.path.expanduser("~/.jarvis")
|
27
|
+
if os.path.exists(user_jarvis):
|
28
|
+
try:
|
29
|
+
with open(user_jarvis, "r", encoding="utf-8") as f:
|
30
|
+
user_tasks = yaml.safe_load(f)
|
31
|
+
|
32
|
+
if isinstance(user_tasks, dict):
|
33
|
+
# 验证并添加用户目录的任务
|
34
|
+
for name, desc in user_tasks.items():
|
35
|
+
if desc: # 确保描述不为空
|
36
|
+
tasks[str(name)] = str(desc)
|
37
|
+
else:
|
38
|
+
PrettyOutput.print("Warning: ~/.jarvis file should contain a dictionary of task_name: task_description", OutputType.ERROR)
|
39
|
+
except Exception as e:
|
40
|
+
PrettyOutput.print(f"Error loading ~/.jarvis file: {str(e)}", OutputType.ERROR)
|
41
|
+
|
42
|
+
# 检查当前目录下的 .jarvis
|
43
|
+
if os.path.exists(".jarvis"):
|
44
|
+
try:
|
45
|
+
with open(".jarvis", "r", encoding="utf-8") as f:
|
46
|
+
local_tasks = yaml.safe_load(f)
|
47
|
+
|
48
|
+
if isinstance(local_tasks, dict):
|
49
|
+
# 验证并添加当前目录的任务,如果有重名则覆盖用户目录的任务
|
50
|
+
for name, desc in local_tasks.items():
|
51
|
+
if desc: # 确保描述不为空
|
52
|
+
tasks[str(name)] = str(desc)
|
53
|
+
else:
|
54
|
+
PrettyOutput.print("Warning: .jarvis file should contain a dictionary of task_name: task_description", OutputType.ERROR)
|
55
|
+
except Exception as e:
|
56
|
+
PrettyOutput.print(f"Error loading .jarvis file: {str(e)}", OutputType.ERROR)
|
57
|
+
|
58
|
+
return tasks
|
59
|
+
|
60
|
+
def select_task(tasks: dict) -> str:
|
61
|
+
"""Let user select a task from the list or skip. Returns task description if selected."""
|
62
|
+
if not tasks:
|
63
|
+
return ""
|
64
|
+
|
65
|
+
# Convert tasks to list for ordered display
|
66
|
+
task_names = list(tasks.keys())
|
67
|
+
|
68
|
+
PrettyOutput.print("\nAvailable tasks:", OutputType.INFO)
|
69
|
+
for i, name in enumerate(task_names, 1):
|
70
|
+
PrettyOutput.print(f"[{i}] {name}", OutputType.INFO)
|
71
|
+
PrettyOutput.print("[0] 跳过预定义任务", OutputType.INFO)
|
72
|
+
|
73
|
+
|
74
|
+
while True:
|
75
|
+
try:
|
76
|
+
choice = prompt(
|
77
|
+
"\n请选择一个任务编号(0跳过): ",
|
78
|
+
).strip()
|
79
|
+
|
80
|
+
if not choice:
|
81
|
+
return ""
|
82
|
+
|
83
|
+
choice = int(choice)
|
84
|
+
if choice == 0:
|
85
|
+
return ""
|
86
|
+
elif 1 <= choice <= len(task_names):
|
87
|
+
selected_name = task_names[choice - 1]
|
88
|
+
return tasks[selected_name] # Return the task description
|
89
|
+
else:
|
90
|
+
PrettyOutput.print("Invalid choice. Please select a number from the list.", OutputType.ERROR)
|
91
|
+
|
92
|
+
except KeyboardInterrupt:
|
93
|
+
return "" # Return empty on Ctrl+C
|
94
|
+
except EOFError:
|
95
|
+
return "" # Return empty on Ctrl+D
|
96
|
+
except Exception as e:
|
97
|
+
PrettyOutput.print(f"选择失败: {str(e)}", OutputType.ERROR)
|
98
|
+
continue
|
99
|
+
|
100
|
+
def main():
|
101
|
+
"""Main entry point for Jarvis."""
|
102
|
+
# Add argument parser
|
103
|
+
parser = argparse.ArgumentParser(description='Jarvis AI Assistant')
|
104
|
+
parser.add_argument('-f', '--files', nargs='*', help='List of files to process')
|
105
|
+
parser.add_argument('--keep-history', action='store_true', help='Keep chat history (do not delete chat session)')
|
106
|
+
parser.add_argument('-m', '--model', default='kimi', help='选择模型')
|
107
|
+
args = parser.parse_args()
|
108
|
+
|
109
|
+
load_env_from_file()
|
110
|
+
|
111
|
+
ModelRegistry.get_model_registry().set_global_model(args.model)
|
112
|
+
|
113
|
+
try:
|
114
|
+
# 获取全局模型实例
|
115
|
+
agent = Agent()
|
116
|
+
|
117
|
+
# 欢迎信息
|
118
|
+
PrettyOutput.print(f"Jarvis 已初始化 - With {args.model}", OutputType.SYSTEM)
|
119
|
+
if args.keep_history:
|
120
|
+
PrettyOutput.print("已启用历史保留模式", OutputType.INFO)
|
121
|
+
|
122
|
+
# 加载预定义任务
|
123
|
+
tasks = load_tasks()
|
124
|
+
if tasks:
|
125
|
+
selected_task = select_task(tasks)
|
126
|
+
if selected_task:
|
127
|
+
PrettyOutput.print(f"\n执行任务: {selected_task}", OutputType.INFO)
|
128
|
+
agent.run(selected_task, args.files, keep_history=args.keep_history)
|
129
|
+
return 0
|
130
|
+
|
131
|
+
# 如果没有选择预定义任务,进入交互模式
|
132
|
+
while True:
|
133
|
+
try:
|
134
|
+
user_input = get_multiline_input("请输入您的任务(输入空行退出):")
|
135
|
+
if not user_input or user_input == "__interrupt__":
|
136
|
+
break
|
137
|
+
agent.run(user_input, args.files, keep_history=args.keep_history)
|
138
|
+
except Exception as e:
|
139
|
+
PrettyOutput.print(f"错误: {str(e)}", OutputType.ERROR)
|
140
|
+
|
141
|
+
except Exception as e:
|
142
|
+
PrettyOutput.print(f"初始化错误: {str(e)}", OutputType.ERROR)
|
143
|
+
return 1
|
144
|
+
|
145
|
+
return 0
|
146
|
+
|
147
|
+
if __name__ == "__main__":
|
148
|
+
exit(main())
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
jarvis/models/base.py
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
from typing import Dict, List
|
3
|
+
from ..utils import OutputType, PrettyOutput
|
4
|
+
|
5
|
+
|
6
|
+
class BaseModel(ABC):
|
7
|
+
"""大语言模型基类"""
|
8
|
+
|
9
|
+
def __init__(self):
|
10
|
+
"""初始化模型"""
|
11
|
+
pass
|
12
|
+
|
13
|
+
|
14
|
+
@abstractmethod
|
15
|
+
def chat(self, message: str) -> str:
|
16
|
+
"""执行对话"""
|
17
|
+
raise NotImplementedError("chat is not implemented")
|
18
|
+
|
19
|
+
def upload_files(self, file_list: List[str]) -> List[Dict]:
|
20
|
+
"""上传文件"""
|
21
|
+
raise NotImplementedError("upload_files is not implemented")
|
22
|
+
|
23
|
+
def reset(self):
|
24
|
+
"""重置模型"""
|
25
|
+
raise NotImplementedError("reset is not implemented")
|
26
|
+
|
27
|
+
@abstractmethod
|
28
|
+
def name(self) -> str:
|
29
|
+
"""模型名称"""
|
30
|
+
raise NotImplementedError("name is not implemented")
|
31
|
+
|
32
|
+
@abstractmethod
|
33
|
+
def delete_chat(self)->bool:
|
34
|
+
"""删除对话"""
|
35
|
+
raise NotImplementedError("delete_chat is not implemented")
|
36
|
+
|
37
|
+
def set_system_message(self, message: str):
|
38
|
+
"""设置系统消息"""
|
39
|
+
raise NotImplementedError("set_system_message is not implemented")
|