jarvis-ai-assistant 0.1.224__py3-none-any.whl → 0.1.225__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 +25 -6
- jarvis/jarvis_agent/jarvis.py +81 -32
- jarvis/jarvis_agent/main.py +6 -2
- jarvis/jarvis_code_agent/code_agent.py +5 -3
- jarvis/jarvis_code_analysis/checklists/loader.py +20 -6
- jarvis/jarvis_platform_manager/main.py +18 -6
- jarvis/jarvis_rag/llm_interface.py +1 -3
- jarvis/jarvis_smart_shell/main.py +18 -12
- jarvis/jarvis_tools/ask_user.py +1 -0
- jarvis/jarvis_tools/registry.py +4 -1
- jarvis/jarvis_tools/search_web.py +19 -9
- jarvis/jarvis_utils/builtin_replace_map.py +0 -1
- jarvis/jarvis_utils/utils.py +1 -0
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.1.225.dist-info}/METADATA +3 -2
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.1.225.dist-info}/RECORD +20 -20
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.1.225.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.1.225.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.1.225.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.1.225.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
@@ -213,6 +213,7 @@ class Agent:
|
|
213
213
|
"""
|
214
214
|
)
|
215
215
|
self.first = True
|
216
|
+
self.run_input_handlers_next_turn = False
|
216
217
|
|
217
218
|
def set_user_data(self, key: str, value: Any):
|
218
219
|
"""Sets user data in the session."""
|
@@ -236,6 +237,10 @@ class Agent:
|
|
236
237
|
"""Sets the addon prompt in the session."""
|
237
238
|
self.session.set_addon_prompt(addon_prompt)
|
238
239
|
|
240
|
+
def set_run_input_handlers_next_turn(self, value: bool):
|
241
|
+
"""Sets the flag to run input handlers on the next turn."""
|
242
|
+
self.run_input_handlers_next_turn = value
|
243
|
+
|
239
244
|
def set_after_tool_call_cb(self, cb: Callable[[Any], None]): # type: ignore
|
240
245
|
"""设置工具调用后回调函数。
|
241
246
|
|
@@ -264,7 +269,9 @@ class Agent:
|
|
264
269
|
return handler
|
265
270
|
return None
|
266
271
|
|
267
|
-
def _call_model(
|
272
|
+
def _call_model(
|
273
|
+
self, message: str, need_complete: bool = False, run_input_handlers: bool = True
|
274
|
+
) -> str:
|
268
275
|
"""调用AI模型并实现重试逻辑
|
269
276
|
|
270
277
|
参数:
|
@@ -280,10 +287,11 @@ class Agent:
|
|
280
287
|
3. 会自动添加附加提示
|
281
288
|
4. 会检查并处理上下文长度限制
|
282
289
|
"""
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
290
|
+
if run_input_handlers:
|
291
|
+
for handler in self.input_handler:
|
292
|
+
message, need_return = handler(message, self)
|
293
|
+
if need_return:
|
294
|
+
return message
|
287
295
|
|
288
296
|
if self.session.addon_prompt:
|
289
297
|
message += f"\n\n{self.session.addon_prompt}"
|
@@ -478,12 +486,20 @@ class Agent:
|
|
478
486
|
try:
|
479
487
|
set_agent(self.name, self)
|
480
488
|
|
489
|
+
run_input_handlers = True
|
481
490
|
while True:
|
491
|
+
if self.run_input_handlers_next_turn:
|
492
|
+
run_input_handlers = True
|
493
|
+
self.run_input_handlers_next_turn = False
|
494
|
+
|
482
495
|
if self.first:
|
483
496
|
self._first_run()
|
484
497
|
try:
|
485
|
-
current_response = self._call_model(
|
498
|
+
current_response = self._call_model(
|
499
|
+
self.session.prompt, True, run_input_handlers
|
500
|
+
)
|
486
501
|
self.session.prompt = ""
|
502
|
+
run_input_handlers = False
|
487
503
|
|
488
504
|
if get_interrupt():
|
489
505
|
set_interrupt(False)
|
@@ -491,6 +507,7 @@ class Agent:
|
|
491
507
|
f"模型交互期间被中断,请输入用户干预信息:"
|
492
508
|
)
|
493
509
|
if user_input:
|
510
|
+
run_input_handlers = True
|
494
511
|
# 如果有工具调用且用户确认继续,则将干预信息和工具执行结果拼接为prompt
|
495
512
|
if any(
|
496
513
|
handler.can_handle(current_response)
|
@@ -502,6 +519,7 @@ class Agent:
|
|
502
519
|
self.session.prompt = (
|
503
520
|
f"{user_input}\n\n{current_response}"
|
504
521
|
)
|
522
|
+
run_input_handlers = False
|
505
523
|
continue
|
506
524
|
self.session.prompt += f"{user_input}"
|
507
525
|
continue
|
@@ -529,6 +547,7 @@ class Agent:
|
|
529
547
|
|
530
548
|
if user_input:
|
531
549
|
self.session.prompt = user_input
|
550
|
+
run_input_handlers = True
|
532
551
|
continue
|
533
552
|
|
534
553
|
if not user_input:
|
jarvis/jarvis_agent/jarvis.py
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
import argparse
|
3
3
|
import os
|
4
|
+
import shutil
|
5
|
+
import subprocess
|
4
6
|
import sys
|
5
|
-
from
|
7
|
+
from pathlib import Path
|
8
|
+
from typing import Dict, Optional
|
6
9
|
|
7
10
|
import yaml # type: ignore
|
8
11
|
from prompt_toolkit import prompt # type: ignore
|
@@ -106,8 +109,8 @@ def _select_task(tasks: Dict[str, str]) -> str:
|
|
106
109
|
PrettyOutput.print(f"选择任务失败: {str(val_err)}", OutputType.ERROR)
|
107
110
|
|
108
111
|
|
109
|
-
def
|
110
|
-
|
112
|
+
def _parse_args() -> argparse.Namespace:
|
113
|
+
"""Parse command line arguments."""
|
111
114
|
parser = argparse.ArgumentParser(description="Jarvis AI assistant")
|
112
115
|
parser.add_argument(
|
113
116
|
"--llm_type",
|
@@ -129,44 +132,90 @@ def main() -> None:
|
|
129
132
|
help="Restore session from .jarvis/saved_session.json",
|
130
133
|
default=False,
|
131
134
|
)
|
132
|
-
|
133
|
-
|
134
|
-
"欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config
|
135
|
+
parser.add_argument(
|
136
|
+
"-e", "--edit", action="store_true", help="Edit the configuration file"
|
135
137
|
)
|
138
|
+
return parser.parse_args()
|
136
139
|
|
137
|
-
try:
|
138
|
-
agent = Agent(
|
139
|
-
system_prompt=origin_agent_system_prompt,
|
140
|
-
llm_type=args.llm_type,
|
141
|
-
input_handler=[shell_input_handler, builtin_input_handler],
|
142
|
-
output_handler=[ToolRegistry()],
|
143
|
-
need_summary=False,
|
144
|
-
)
|
145
140
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
else:
|
151
|
-
PrettyOutput.print("无法恢复会话。", OutputType.WARNING)
|
141
|
+
def _handle_edit_mode(args: argparse.Namespace) -> None:
|
142
|
+
"""If edit flag is set, open config file in editor and exit."""
|
143
|
+
if not args.edit:
|
144
|
+
return
|
152
145
|
|
153
|
-
|
154
|
-
|
155
|
-
|
146
|
+
config_file_path = (
|
147
|
+
Path(args.config)
|
148
|
+
if args.config
|
149
|
+
else Path(os.path.expanduser("~/.jarvis/config.yaml"))
|
150
|
+
)
|
151
|
+
editors = ["nvim", "vim", "vi"]
|
152
|
+
editor = next((e for e in editors if shutil.which(e)), None)
|
153
|
+
|
154
|
+
if editor:
|
155
|
+
try:
|
156
|
+
subprocess.run([editor, str(config_file_path)], check=True)
|
156
157
|
sys.exit(0)
|
158
|
+
except (subprocess.CalledProcessError, FileNotFoundError) as e:
|
159
|
+
PrettyOutput.print(f"Failed to open editor: {e}", OutputType.ERROR)
|
160
|
+
sys.exit(1)
|
161
|
+
else:
|
162
|
+
PrettyOutput.print(
|
163
|
+
"No suitable editor found (nvim, vim, vi).", OutputType.ERROR
|
164
|
+
)
|
165
|
+
sys.exit(1)
|
166
|
+
|
157
167
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
168
|
+
def _initialize_agent(args: argparse.Namespace) -> Agent:
|
169
|
+
"""Initialize the agent and restore session if requested."""
|
170
|
+
agent = Agent(
|
171
|
+
system_prompt=origin_agent_system_prompt,
|
172
|
+
llm_type=args.llm_type,
|
173
|
+
input_handler=[shell_input_handler, builtin_input_handler],
|
174
|
+
output_handler=[ToolRegistry()], # type: ignore
|
175
|
+
need_summary=False,
|
176
|
+
)
|
164
177
|
|
165
|
-
|
166
|
-
|
167
|
-
|
178
|
+
# 尝试恢复会话
|
179
|
+
if args.restore_session:
|
180
|
+
if agent.restore_session():
|
181
|
+
PrettyOutput.print("会话已成功恢复。", OutputType.SUCCESS)
|
182
|
+
else:
|
183
|
+
PrettyOutput.print("无法恢复会话。", OutputType.WARNING)
|
184
|
+
return agent
|
185
|
+
|
186
|
+
|
187
|
+
def _get_and_run_task(agent: Agent, task_content: Optional[str] = None) -> None:
|
188
|
+
"""Get task from various sources and run it."""
|
189
|
+
# 优先处理命令行直接传入的任务
|
190
|
+
if task_content:
|
191
|
+
agent.run(task_content)
|
168
192
|
sys.exit(0)
|
169
193
|
|
194
|
+
if agent.first:
|
195
|
+
tasks = _load_tasks()
|
196
|
+
if tasks and (selected_task := _select_task(tasks)):
|
197
|
+
PrettyOutput.print(f"开始执行任务: \n{selected_task}", OutputType.INFO)
|
198
|
+
agent.run(selected_task)
|
199
|
+
sys.exit(0)
|
200
|
+
|
201
|
+
user_input = get_multiline_input("请输入你的任务(输入空行退出):")
|
202
|
+
if user_input:
|
203
|
+
agent.run(user_input)
|
204
|
+
sys.exit(0)
|
205
|
+
|
206
|
+
|
207
|
+
def main() -> None:
|
208
|
+
"""Main function for Jarvis AI assistant."""
|
209
|
+
args = _parse_args()
|
210
|
+
_handle_edit_mode(args)
|
211
|
+
|
212
|
+
init_env(
|
213
|
+
"欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config
|
214
|
+
)
|
215
|
+
|
216
|
+
try:
|
217
|
+
agent = _initialize_agent(args)
|
218
|
+
_get_and_run_task(agent, args.task)
|
170
219
|
except Exception as err: # pylint: disable=broad-except
|
171
220
|
PrettyOutput.print(f"初始化错误: {str(err)}", OutputType.ERROR)
|
172
221
|
sys.exit(1)
|
jarvis/jarvis_agent/main.py
CHANGED
@@ -20,7 +20,9 @@ def load_config(config_path: str) -> dict:
|
|
20
20
|
dict: 配置字典
|
21
21
|
"""
|
22
22
|
if not os.path.exists(config_path):
|
23
|
-
PrettyOutput.print(
|
23
|
+
PrettyOutput.print(
|
24
|
+
f"配置文件 {config_path} 不存在,使用默认配置", OutputType.WARNING
|
25
|
+
)
|
24
26
|
return {}
|
25
27
|
|
26
28
|
with open(config_path, "r", encoding="utf-8", errors="ignore") as f:
|
@@ -53,7 +55,9 @@ def main():
|
|
53
55
|
args = parser.parse_args()
|
54
56
|
|
55
57
|
# Initialize environment
|
56
|
-
init_env(
|
58
|
+
init_env(
|
59
|
+
"欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config
|
60
|
+
)
|
57
61
|
|
58
62
|
# Load configuration
|
59
63
|
config = load_config(args.agent_definition) if args.agent_definition else {}
|
@@ -18,7 +18,10 @@ from jarvis.jarvis_code_agent.lint import get_lint_tools
|
|
18
18
|
from jarvis.jarvis_git_utils.git_commiter import GitCommitTool
|
19
19
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
20
20
|
from jarvis.jarvis_tools.registry import ToolRegistry
|
21
|
-
from jarvis.jarvis_utils.config import
|
21
|
+
from jarvis.jarvis_utils.config import (
|
22
|
+
is_confirm_before_apply_patch,
|
23
|
+
is_enable_static_analysis,
|
24
|
+
)
|
22
25
|
from jarvis.jarvis_utils.git_utils import (
|
23
26
|
confirm_add_new_files,
|
24
27
|
find_git_root_and_cd,
|
@@ -54,7 +57,6 @@ class CodeAgent:
|
|
54
57
|
"search_web",
|
55
58
|
"ask_user",
|
56
59
|
"read_code",
|
57
|
-
"methodology",
|
58
60
|
"rewrite_file",
|
59
61
|
]
|
60
62
|
)
|
@@ -116,7 +118,7 @@ class CodeAgent:
|
|
116
118
|
system_prompt=code_system_prompt,
|
117
119
|
name="CodeAgent",
|
118
120
|
auto_complete=False,
|
119
|
-
output_handler=[tool_registry, EditFileHandler()],
|
121
|
+
output_handler=[tool_registry, EditFileHandler()], # type: ignore
|
120
122
|
llm_type=llm_type,
|
121
123
|
input_handler=[shell_input_handler, builtin_input_handler],
|
122
124
|
need_summary=need_summary,
|
@@ -5,12 +5,26 @@ Utility module for loading language-specific code review checklists.
|
|
5
5
|
from typing import Dict, Optional
|
6
6
|
|
7
7
|
# Import checklist modules
|
8
|
-
from jarvis.jarvis_code_analysis.checklists import (
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
8
|
+
from jarvis.jarvis_code_analysis.checklists import (
|
9
|
+
c_cpp,
|
10
|
+
csharp,
|
11
|
+
data_format,
|
12
|
+
devops,
|
13
|
+
docs,
|
14
|
+
go,
|
15
|
+
infrastructure,
|
16
|
+
java,
|
17
|
+
javascript,
|
18
|
+
kotlin,
|
19
|
+
php,
|
20
|
+
python,
|
21
|
+
ruby,
|
22
|
+
rust,
|
23
|
+
shell,
|
24
|
+
sql,
|
25
|
+
swift,
|
26
|
+
web,
|
27
|
+
)
|
14
28
|
|
15
29
|
# Map of language identifiers to their checklist content
|
16
30
|
CHECKLIST_MAP = {
|
@@ -188,9 +188,13 @@ def chat_with_model(platform_name: str, model_name: str, system_prompt: str) ->
|
|
188
188
|
for entry in conversation_history:
|
189
189
|
file_obj.write(f"{entry['role']}: {entry['content']}\n\n")
|
190
190
|
|
191
|
-
PrettyOutput.print(
|
191
|
+
PrettyOutput.print(
|
192
|
+
f"所有对话已保存到 {file_path}", OutputType.SUCCESS
|
193
|
+
)
|
192
194
|
except Exception as exc:
|
193
|
-
PrettyOutput.print(
|
195
|
+
PrettyOutput.print(
|
196
|
+
f"保存所有对话失败: {str(exc)}", OutputType.ERROR
|
197
|
+
)
|
194
198
|
continue
|
195
199
|
|
196
200
|
# Check if it is a save_session command
|
@@ -211,7 +215,9 @@ def chat_with_model(platform_name: str, model_name: str, system_prompt: str) ->
|
|
211
215
|
file_path = file_path[1:-1]
|
212
216
|
|
213
217
|
if platform.save(file_path):
|
214
|
-
PrettyOutput.print(
|
218
|
+
PrettyOutput.print(
|
219
|
+
f"会话已保存到 {file_path}", OutputType.SUCCESS
|
220
|
+
)
|
215
221
|
else:
|
216
222
|
PrettyOutput.print("保存会话失败", OutputType.ERROR)
|
217
223
|
except Exception as exc:
|
@@ -237,7 +243,9 @@ def chat_with_model(platform_name: str, model_name: str, system_prompt: str) ->
|
|
237
243
|
|
238
244
|
if platform.restore(file_path):
|
239
245
|
conversation_history = [] # Clear local history after loading
|
240
|
-
PrettyOutput.print(
|
246
|
+
PrettyOutput.print(
|
247
|
+
f"会话已从 {file_path} 加载", OutputType.SUCCESS
|
248
|
+
)
|
241
249
|
else:
|
242
250
|
PrettyOutput.print("加载会话失败", OutputType.ERROR)
|
243
251
|
except Exception as exc:
|
@@ -433,8 +441,12 @@ def main() -> None:
|
|
433
441
|
service_parser.add_argument(
|
434
442
|
"--port", type=int, default=8000, help="服务端口 (默认: 8000)"
|
435
443
|
)
|
436
|
-
service_parser.add_argument(
|
437
|
-
|
444
|
+
service_parser.add_argument(
|
445
|
+
"--platform", "-p", help="指定默认平台,当客户端未指定平台时使用"
|
446
|
+
)
|
447
|
+
service_parser.add_argument(
|
448
|
+
"--model", "-m", help="指定默认模型,当客户端未指定平台时使用"
|
449
|
+
)
|
438
450
|
service_parser.set_defaults(func=service_command)
|
439
451
|
|
440
452
|
# role subcommand
|
@@ -101,9 +101,7 @@ class JarvisPlatform_LLM(LLMInterface):
|
|
101
101
|
try:
|
102
102
|
self.registry = PlatformRegistry.get_global_platform_registry()
|
103
103
|
self.platform: BasePlatform = self.registry.get_normal_platform()
|
104
|
-
self.platform.set_suppress_output(
|
105
|
-
False
|
106
|
-
) # 确保模型没有控制台输出
|
104
|
+
self.platform.set_suppress_output(False) # 确保模型没有控制台输出
|
107
105
|
print(f"🚀 已初始化 Jarvis 平台 LLM,模型: {self.platform.name()}")
|
108
106
|
except Exception as e:
|
109
107
|
print(f"❌ 初始化 Jarvis 平台 LLM 失败: {e}")
|
@@ -20,34 +20,37 @@ def execute_command(command: str, should_run: bool) -> None:
|
|
20
20
|
|
21
21
|
def _check_fish_shell() -> bool:
|
22
22
|
"""Check if current shell is fish
|
23
|
-
|
23
|
+
|
24
24
|
Returns:
|
25
25
|
bool: True if fish shell, False otherwise
|
26
26
|
"""
|
27
27
|
return get_shell_name() == "fish"
|
28
28
|
|
29
|
+
|
29
30
|
def _get_config_file() -> str:
|
30
31
|
"""Get fish config file path
|
31
|
-
|
32
|
+
|
32
33
|
Returns:
|
33
34
|
str: Path to fish config file
|
34
35
|
"""
|
35
36
|
return os.path.expanduser("~/.config/fish/config.fish")
|
36
37
|
|
38
|
+
|
37
39
|
def _get_markers() -> Tuple[str, str]:
|
38
40
|
"""Get start and end markers for JSS completion
|
39
|
-
|
41
|
+
|
40
42
|
Returns:
|
41
43
|
Tuple[str, str]: (start_marker, end_marker)
|
42
44
|
"""
|
43
45
|
return (
|
44
46
|
"# ===== JARVIS JSS FISH COMPLETION START =====",
|
45
|
-
"# ===== JARVIS JSS FISH COMPLETION END ====="
|
47
|
+
"# ===== JARVIS JSS FISH COMPLETION END =====",
|
46
48
|
)
|
47
49
|
|
50
|
+
|
48
51
|
def install_jss_completion() -> int:
|
49
52
|
"""Install JSS fish shell command completion
|
50
|
-
|
53
|
+
|
51
54
|
Returns:
|
52
55
|
int: 0 if success, 1 if failed
|
53
56
|
"""
|
@@ -70,7 +73,8 @@ def install_jss_completion() -> int:
|
|
70
73
|
return 0
|
71
74
|
|
72
75
|
with open(config_file, "a") as f:
|
73
|
-
f.write(
|
76
|
+
f.write(
|
77
|
+
f"""
|
74
78
|
{start_marker}
|
75
79
|
function fish_command_not_found
|
76
80
|
if test (string length "$argv") -lt 10
|
@@ -83,13 +87,15 @@ function __fish_command_not_found_handler --on-event fish_command_not_found
|
|
83
87
|
fish_command_not_found "$argv"
|
84
88
|
end
|
85
89
|
{end_marker}
|
86
|
-
"""
|
90
|
+
"""
|
91
|
+
)
|
87
92
|
print("JSS fish completion已安装,请执行: source ~/.config/fish/config.fish")
|
88
93
|
return 0
|
89
94
|
|
95
|
+
|
90
96
|
def uninstall_jss_completion() -> int:
|
91
97
|
"""Uninstall JSS fish shell command completion
|
92
|
-
|
98
|
+
|
93
99
|
Returns:
|
94
100
|
int: 0 if success, 1 if failed
|
95
101
|
"""
|
@@ -112,10 +118,10 @@ def uninstall_jss_completion() -> int:
|
|
112
118
|
return 0
|
113
119
|
|
114
120
|
new_content = content.split(start_marker)[0] + content.split(end_marker)[-1]
|
115
|
-
|
121
|
+
|
116
122
|
with open(config_file, "w") as f:
|
117
123
|
f.write(new_content)
|
118
|
-
|
124
|
+
|
119
125
|
print("JSS fish completion已卸载,请执行: source ~/.config/fish/config.fish")
|
120
126
|
return 0
|
121
127
|
|
@@ -205,7 +211,7 @@ Example:
|
|
205
211
|
install_parser.add_argument(
|
206
212
|
"--shell", choices=["fish"], default="fish", help="指定shell类型(仅支持fish)"
|
207
213
|
)
|
208
|
-
|
214
|
+
|
209
215
|
# 添加uninstall子命令
|
210
216
|
uninstall_parser = subparsers.add_parser(
|
211
217
|
"uninstall", help="卸载JSS fish shell命令补全功能"
|
@@ -232,7 +238,7 @@ Example:
|
|
232
238
|
print(f"错误: 不支持的shell类型: {args.shell}, 仅支持fish")
|
233
239
|
return 1
|
234
240
|
return uninstall_jss_completion()
|
235
|
-
|
241
|
+
|
236
242
|
# 处理request命令
|
237
243
|
if not args.request:
|
238
244
|
# 检查是否在交互式终端中运行
|
jarvis/jarvis_tools/ask_user.py
CHANGED
jarvis/jarvis_tools/registry.py
CHANGED
@@ -565,7 +565,10 @@ class ToolRegistry(OutputHandlerProtocol):
|
|
565
565
|
ot("TOOL_CALL") + r"(.*?)" + ct("TOOL_CALL"), content, re.DOTALL
|
566
566
|
)
|
567
567
|
if not data:
|
568
|
-
return
|
568
|
+
return (
|
569
|
+
{},
|
570
|
+
f"只有{ot('TOOL_CALL')}标签,未找到{ct('TOOL_CALL')}标签,调用格式错误,请检查工具调用格式。\n{tool_call_help}",
|
571
|
+
)
|
569
572
|
ret = []
|
570
573
|
for item in data:
|
571
574
|
try:
|
@@ -3,7 +3,7 @@
|
|
3
3
|
from typing import Any, Dict
|
4
4
|
|
5
5
|
import httpx
|
6
|
-
from
|
6
|
+
from markdownify import markdownify as md
|
7
7
|
from ddgs import DDGS
|
8
8
|
|
9
9
|
from jarvis.jarvis_agent import Agent
|
@@ -27,7 +27,7 @@ class SearchWebTool:
|
|
27
27
|
"""Performs a web search, scrapes content, and summarizes the results."""
|
28
28
|
try:
|
29
29
|
PrettyOutput.print("▶️ 使用 DuckDuckGo 开始网页搜索...", OutputType.INFO)
|
30
|
-
results = list(DDGS().text(query, max_results=
|
30
|
+
results = list(DDGS().text(query, max_results=50))
|
31
31
|
|
32
32
|
if not results:
|
33
33
|
return {
|
@@ -36,19 +36,29 @@ class SearchWebTool:
|
|
36
36
|
"success": False,
|
37
37
|
}
|
38
38
|
|
39
|
-
urls = [r["href"] for r in results]
|
40
39
|
full_content = ""
|
41
40
|
visited_urls = []
|
41
|
+
visited_count = 0
|
42
|
+
|
43
|
+
for r in results:
|
44
|
+
if visited_count >= 10:
|
45
|
+
PrettyOutput.print("ℹ️ 已成功获取10个网页,停止抓取。", OutputType.INFO)
|
46
|
+
break
|
47
|
+
|
48
|
+
url = r["href"]
|
49
|
+
title = r.get("title", url)
|
42
50
|
|
43
|
-
for url in urls:
|
44
51
|
try:
|
45
|
-
PrettyOutput.print(
|
52
|
+
PrettyOutput.print(
|
53
|
+
f"📄 ({visited_count + 1}/10) 正在抓取: {title} ({url})",
|
54
|
+
OutputType.INFO,
|
55
|
+
)
|
46
56
|
response = http_get(url, timeout=10.0, follow_redirects=True)
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
full_content += body.get_text(" ", strip=True) + "\n\n"
|
57
|
+
content = md(response.text, strip=['script', 'style'])
|
58
|
+
if content:
|
59
|
+
full_content += content + "\n\n"
|
51
60
|
visited_urls.append(url)
|
61
|
+
visited_count += 1
|
52
62
|
except httpx.HTTPStatusError as e:
|
53
63
|
PrettyOutput.print(
|
54
64
|
f"⚠️ HTTP错误 {e.response.status_code} 访问 {url}",
|
jarvis/jarvis_utils/utils.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: jarvis-ai-assistant
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.225
|
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
|
@@ -57,8 +57,8 @@ Requires-Dist: pyte==0.8.2
|
|
57
57
|
Requires-Dist: httpx>=0.28.1
|
58
58
|
Requires-Dist: pyyaml>=5.3.1
|
59
59
|
Requires-Dist: ddgs==9.0.2
|
60
|
-
Requires-Dist: beautifulsoup4==4.13.4
|
61
60
|
Requires-Dist: lxml==6.0.0
|
61
|
+
Requires-Dist: markdownify>=1.1.0
|
62
62
|
Provides-Extra: dev
|
63
63
|
Requires-Dist: pytest; extra == "dev"
|
64
64
|
Requires-Dist: black; extra == "dev"
|
@@ -158,6 +158,7 @@ jarvis --llm_type thinking -t "初始任务"
|
|
158
158
|
| `-t/--task` | 直接从命令行输入任务内容 |
|
159
159
|
| `-f/--config` | 自定义配置文件的路径 |
|
160
160
|
| `--restore-session` | 从 .jarvis/saved_session.json 恢复会话 |
|
161
|
+
| `-e/--edit` | 编辑配置文件 |
|
161
162
|
|
162
163
|
#### 4. 工作流程
|
163
164
|
1. 初始化环境
|
@@ -1,9 +1,9 @@
|
|
1
|
-
jarvis/__init__.py,sha256=
|
2
|
-
jarvis/jarvis_agent/__init__.py,sha256=
|
1
|
+
jarvis/__init__.py,sha256=46Ob6ZTm4a9stXblcxcvfaE4NlTYqHOyTFezByeVN_Y,75
|
2
|
+
jarvis/jarvis_agent/__init__.py,sha256=mpNT4SPLYyUP3vb4zR8GM04pOej8MpnMqfkoz5ZARSQ,22412
|
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
|
5
|
-
jarvis/jarvis_agent/jarvis.py,sha256=
|
6
|
-
jarvis/jarvis_agent/main.py,sha256=
|
5
|
+
jarvis/jarvis_agent/jarvis.py,sha256=5Lkh2RbVqL_se8ZWcXxlh7XiJDhac8fxRtWmMHHO-q8,7803
|
6
|
+
jarvis/jarvis_agent/main.py,sha256=W23ORF8mIxZv4GTLPuR1SlrioJLT0dLeFXrYAAMSc1A,3091
|
7
7
|
jarvis/jarvis_agent/output_handler.py,sha256=P7oWpXBGFfOsWq7cIhS_z9crkQ19ES7qU5pM92KKjAs,1172
|
8
8
|
jarvis/jarvis_agent/prompt_builder.py,sha256=PH1fPDVa8z_RXkoXHJFNDf8PQjUoLNLYwkh2lC__p40,1705
|
9
9
|
jarvis/jarvis_agent/prompts.py,sha256=e8i-3kaGr96mlzL3UUhQUHFDfbJSoE4xiF9TDksNDm4,7720
|
@@ -12,7 +12,7 @@ jarvis/jarvis_agent/session_manager.py,sha256=DnvI9rWkVmkyO1XfKZyo9lTn4ajg4ccwzE
|
|
12
12
|
jarvis/jarvis_agent/shell_input_handler.py,sha256=1IboqdxcJuoIqRpmDU10GugR9fWXUHyCEbVF4nIWbyo,1328
|
13
13
|
jarvis/jarvis_agent/tool_executor.py,sha256=nIq-sPNgrtimtM-IHpN09cWmId8jDzWRdCFoRzXnnoo,1721
|
14
14
|
jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
15
|
-
jarvis/jarvis_code_agent/code_agent.py,sha256=
|
15
|
+
jarvis/jarvis_code_agent/code_agent.py,sha256=ZTvZ6tCVMv6nJBteLy39q0qtsg4OsvcIeg3ip7szVnc,18374
|
16
16
|
jarvis/jarvis_code_agent/lint.py,sha256=LZPsfyZPMo7Wm7LN4osZocuNJwZx1ojacO3MlF870x8,4009
|
17
17
|
jarvis/jarvis_code_analysis/code_review.py,sha256=Huia4w1SkhxfzAk2GNC75uo3a_BcVTCDbj0rx8_t0r4,30424
|
18
18
|
jarvis/jarvis_code_analysis/checklists/__init__.py,sha256=LIXAYa1sW3l7foP6kohLWnE98I_EQ0T7z5bYKHq6rJA,78
|
@@ -26,7 +26,7 @@ jarvis/jarvis_code_analysis/checklists/infrastructure.py,sha256=7z5MZnOUT3FpMrTQ
|
|
26
26
|
jarvis/jarvis_code_analysis/checklists/java.py,sha256=gWRVhXfsNhRFdthjIiQTkviqLwisuKCrr6gjxP0S9Z4,2085
|
27
27
|
jarvis/jarvis_code_analysis/checklists/javascript.py,sha256=SQkw2I09DaaLxD_WTZjuHn4leUKil68IEPB03BoSYuo,2340
|
28
28
|
jarvis/jarvis_code_analysis/checklists/kotlin.py,sha256=dNSHM1u3R7lxe8BU8ADtDyKJxmj3NUh9ZQuC7HHWHGY,4436
|
29
|
-
jarvis/jarvis_code_analysis/checklists/loader.py,sha256=
|
29
|
+
jarvis/jarvis_code_analysis/checklists/loader.py,sha256=bjE4On6WMLt41bfkCZsHnBpfXF61VPthFPsgNcbH90c,1903
|
30
30
|
jarvis/jarvis_code_analysis/checklists/php.py,sha256=qW34sF9AqLuSVuOVP5yJUHnB9V3-YRQjNPuB3lFI5UY,2481
|
31
31
|
jarvis/jarvis_code_analysis/checklists/python.py,sha256=gjyJ0QPY1CAwqhbDnIyLYruvFduZU5hiKyehAXMHu-I,1452
|
32
32
|
jarvis/jarvis_code_analysis/checklists/ruby.py,sha256=kzwd7Wl6gKrkAANq7_MvA5X5du5r1MeE-EY2Xb43n7U,4274
|
@@ -60,21 +60,21 @@ jarvis/jarvis_platform/registry.py,sha256=1bMy0YZUa8NLzuZlKfC4CBtpa0iniypTxUZk0H
|
|
60
60
|
jarvis/jarvis_platform/tongyi.py,sha256=vSK1b4NhTeHbNhTgGRj4PANXptwCAwitczwK8VXwWwU,22921
|
61
61
|
jarvis/jarvis_platform/yuanbao.py,sha256=AIGQ0VOD_IAwWLnU9G19OG0XAbHpcJDzVWX2VazsyAI,23092
|
62
62
|
jarvis/jarvis_platform_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
63
|
-
jarvis/jarvis_platform_manager/main.py,sha256=
|
63
|
+
jarvis/jarvis_platform_manager/main.py,sha256=ysdM-_2vdOorqQiXiJOpZ50ukD5yPmakRHthK-JIl30,18558
|
64
64
|
jarvis/jarvis_platform_manager/service.py,sha256=hQGWQ2qAlzm_C_lNQDuLORQ4rmjR1P1-V3ou7l2Bv0s,13622
|
65
65
|
jarvis/jarvis_rag/__init__.py,sha256=HRTXgnQxDuaE9x-e3r6SYqhJ5d4DSI_rrIxy2IGY6qk,320
|
66
66
|
jarvis/jarvis_rag/cache.py,sha256=Tqx_Oe-AhuWlMXHGHUaIuG6OEHoHBVZq7mL3kldtFFU,2723
|
67
67
|
jarvis/jarvis_rag/cli.py,sha256=q1W7XWZ7u7oMckqeNUX7YQoiQ3PzT3Rh-FZvTeG_U3I,13159
|
68
68
|
jarvis/jarvis_rag/embedding_manager.py,sha256=BoV6Vr_3F4zbjBAOQ1FdEBnJXGPwBkv1IEkdRP9CgFw,3338
|
69
|
-
jarvis/jarvis_rag/llm_interface.py,sha256=
|
69
|
+
jarvis/jarvis_rag/llm_interface.py,sha256=eZHibNHD5dFK9yolr3hYNNhAEZUsPA-cIf1uHapI2h8,4338
|
70
70
|
jarvis/jarvis_rag/query_rewriter.py,sha256=JM1Q23zZISze77BleRgTPgNAtLUtLAXkEo3G70kaTK8,2190
|
71
71
|
jarvis/jarvis_rag/rag_pipeline.py,sha256=9yeNRv6qOS2zo7o0b0u3gFmiW_XSivesvPKVJ8e5DlE,6209
|
72
72
|
jarvis/jarvis_rag/reranker.py,sha256=wYUDIMHQL8_tFcQ7GFn_zYHTE1AbKk4a9TRoN2lKtA8,1767
|
73
73
|
jarvis/jarvis_rag/retriever.py,sha256=B6oq1SAh7QAE9G5o0sXyNtLjFodukd8p-Was2QJZXg0,7637
|
74
74
|
jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
75
|
-
jarvis/jarvis_smart_shell/main.py,sha256=
|
75
|
+
jarvis/jarvis_smart_shell/main.py,sha256=3oAl4LbpkiJWCpxqwXF6-vmydZr5HMFKCvkQR94dzLc,6946
|
76
76
|
jarvis/jarvis_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
77
|
-
jarvis/jarvis_tools/ask_user.py,sha256=
|
77
|
+
jarvis/jarvis_tools/ask_user.py,sha256=M6DdLNryCE8y1JcdZHEifUgZkPUEPNKc-zDW5p0Mb1k,2029
|
78
78
|
jarvis/jarvis_tools/base.py,sha256=tFVmK6ppsImW2BzHZmrNmMRiOJdW-4aZP6Me3VxdYcA,1194
|
79
79
|
jarvis/jarvis_tools/edit_file.py,sha256=hM345E9rxS-EkqCZpwwizL6fmPdTadtB798tEO5Ce3g,10417
|
80
80
|
jarvis/jarvis_tools/execute_script.py,sha256=gMarE5yCCSPU6Dp6HlcL2KT-2xCzR-1p-oQNlYOJK58,6157
|
@@ -83,14 +83,14 @@ jarvis/jarvis_tools/generate_new_tool.py,sha256=2YAs8DC7fJnxOkjSmhmSAwqSpBlicVhY
|
|
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=Lfp6UcEw-Gbva-7OUTHOBrT9xYwrGrolvjaSpYhWFwU,26435
|
87
87
|
jarvis/jarvis_tools/rewrite_file.py,sha256=eG_WKg6cVAXmuGwUqlWkcuyay5S8DOzEi8vZCmX3O8w,7255
|
88
|
-
jarvis/jarvis_tools/search_web.py,sha256=
|
88
|
+
jarvis/jarvis_tools/search_web.py,sha256=DDAPjYWTFaF85zsnhJ6VNDSc1BcY8EHus5ymKP9nnPs,5703
|
89
89
|
jarvis/jarvis_tools/virtual_tty.py,sha256=KKr3jpvQWWMPr2o40hlmN6fuXJCN8H4_ma5QU40Citc,16089
|
90
90
|
jarvis/jarvis_tools/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
91
91
|
jarvis/jarvis_tools/cli/main.py,sha256=Mg6TQDxMdzB1Ua1UrZ2EE-uQWsbaeojWaEGHJp2HimA,6375
|
92
92
|
jarvis/jarvis_utils/__init__.py,sha256=67h0ldisGlh3oK4DAeNEL2Bl_VsI3tSmfclasyVlueM,850
|
93
|
-
jarvis/jarvis_utils/builtin_replace_map.py,sha256=
|
93
|
+
jarvis/jarvis_utils/builtin_replace_map.py,sha256=4BurljGuiG_I93EBs7mlFlPm9wYC_4CmdTG5tQWpF6g,1712
|
94
94
|
jarvis/jarvis_utils/config.py,sha256=eTarDAeBdFZx2jX4KQrzanEu4W6hpS5Cw1DHmiB5nN0,8247
|
95
95
|
jarvis/jarvis_utils/embedding.py,sha256=oEOEM2qf16DMYwPsQe6srET9BknyjOdY2ef0jsp3Or8,2714
|
96
96
|
jarvis/jarvis_utils/file_processors.py,sha256=XiM248SHS7lLgQDCbORVFWqinbVDUawYxWDOsLXDxP8,3043
|
@@ -101,10 +101,10 @@ jarvis/jarvis_utils/input.py,sha256=V2w3xV0MO73c4Y4XY_yy9jVNg7MmN76FmAnpKRiJUog,
|
|
101
101
|
jarvis/jarvis_utils/methodology.py,sha256=-cvM6pwgJK7BXCYg2uVjIId_j3v5RUh2z2PBcK_2vj4,8155
|
102
102
|
jarvis/jarvis_utils/output.py,sha256=PRCgudPOB8gMEP3u-g0FGD2c6tBgJhLXUMqNPglfjV8,10813
|
103
103
|
jarvis/jarvis_utils/tag.py,sha256=f211opbbbTcSyzCDwuIK_oCnKhXPNK-RknYyGzY1yD0,431
|
104
|
-
jarvis/jarvis_utils/utils.py,sha256=
|
105
|
-
jarvis_ai_assistant-0.1.
|
106
|
-
jarvis_ai_assistant-0.1.
|
107
|
-
jarvis_ai_assistant-0.1.
|
108
|
-
jarvis_ai_assistant-0.1.
|
109
|
-
jarvis_ai_assistant-0.1.
|
110
|
-
jarvis_ai_assistant-0.1.
|
104
|
+
jarvis/jarvis_utils/utils.py,sha256=OXZ57qTB3dY5e_V6lWZRivYu1cMT1e2VftW7AQBd2X0,15295
|
105
|
+
jarvis_ai_assistant-0.1.225.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
106
|
+
jarvis_ai_assistant-0.1.225.dist-info/METADATA,sha256=s60vmDTdhXx9eGKHz22DIMFUqjqZF_G-r9PwzApQJr4,24094
|
107
|
+
jarvis_ai_assistant-0.1.225.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
108
|
+
jarvis_ai_assistant-0.1.225.dist-info/entry_points.txt,sha256=JXK_n-d9HZ_RLz959CvpK5-UPOCwssn5oAH8dAHuebA,1277
|
109
|
+
jarvis_ai_assistant-0.1.225.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
110
|
+
jarvis_ai_assistant-0.1.225.dist-info/RECORD,,
|
File without changes
|
{jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.1.225.dist-info}/entry_points.txt
RENAMED
File without changes
|
{jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.1.225.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
{jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.1.225.dist-info}/top_level.txt
RENAMED
File without changes
|