jarvis-ai-assistant 0.1.224__py3-none-any.whl → 0.2.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 +33 -11
- jarvis/jarvis_agent/jarvis.py +87 -32
- jarvis/jarvis_agent/main.py +13 -2
- jarvis/jarvis_code_agent/code_agent.py +17 -4
- jarvis/jarvis_code_analysis/checklists/loader.py +20 -6
- jarvis/jarvis_code_analysis/code_review.py +14 -3
- jarvis/jarvis_data/config_schema.json +41 -0
- jarvis/jarvis_git_utils/git_commiter.py +9 -2
- jarvis/jarvis_mcp/sse_mcp_client.py +9 -7
- jarvis/jarvis_mcp/stdio_mcp_client.py +2 -2
- jarvis/jarvis_platform/base.py +28 -13
- 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/generate_new_tool.py +1 -0
- jarvis/jarvis_tools/registry.py +17 -9
- jarvis/jarvis_tools/search_web.py +19 -9
- jarvis/jarvis_utils/builtin_replace_map.py +0 -1
- jarvis/jarvis_utils/config.py +80 -21
- jarvis/jarvis_utils/git_utils.py +2 -2
- jarvis/jarvis_utils/globals.py +17 -11
- jarvis/jarvis_utils/methodology.py +37 -23
- jarvis/jarvis_utils/output.py +2 -2
- jarvis/jarvis_utils/utils.py +138 -3
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/METADATA +49 -12
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/RECORD +32 -32
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
@@ -102,6 +102,7 @@ class Agent:
|
|
102
102
|
name: str = "Jarvis",
|
103
103
|
description: str = "",
|
104
104
|
llm_type: str = "normal",
|
105
|
+
model_group: Optional[str] = None,
|
105
106
|
summary_prompt: Optional[str] = None,
|
106
107
|
auto_complete: bool = False,
|
107
108
|
output_handler: List[OutputHandlerProtocol] = [],
|
@@ -137,11 +138,11 @@ class Agent:
|
|
137
138
|
self.description = description
|
138
139
|
# 初始化平台和模型
|
139
140
|
if llm_type == "thinking":
|
140
|
-
platform_name = get_thinking_platform_name()
|
141
|
-
model_name = get_thinking_model_name()
|
141
|
+
platform_name = get_thinking_platform_name(model_group)
|
142
|
+
model_name = get_thinking_model_name(model_group)
|
142
143
|
else: # 默认为 normal
|
143
|
-
platform_name = get_normal_platform_name()
|
144
|
-
model_name = get_normal_model_name()
|
144
|
+
platform_name = get_normal_platform_name(model_group)
|
145
|
+
model_name = get_normal_model_name(model_group)
|
145
146
|
|
146
147
|
self.model = PlatformRegistry().create_platform(platform_name)
|
147
148
|
if self.model is None:
|
@@ -153,6 +154,8 @@ class Agent:
|
|
153
154
|
if model_name:
|
154
155
|
self.model.set_model_name(model_name)
|
155
156
|
|
157
|
+
self.model.set_model_group(model_group)
|
158
|
+
|
156
159
|
self.user_data: Dict[str, Any] = {}
|
157
160
|
|
158
161
|
self.model.set_suppress_output(False)
|
@@ -197,7 +200,7 @@ class Agent:
|
|
197
200
|
summary_prompt if summary_prompt else DEFAULT_SUMMARY_PROMPT
|
198
201
|
)
|
199
202
|
|
200
|
-
self.max_token_count = get_max_token_count()
|
203
|
+
self.max_token_count = get_max_token_count(model_group)
|
201
204
|
self.auto_complete = auto_complete
|
202
205
|
welcome_message = f"{name} 初始化完成 - 使用 {self.model.name()} 模型"
|
203
206
|
|
@@ -213,6 +216,7 @@ class Agent:
|
|
213
216
|
"""
|
214
217
|
)
|
215
218
|
self.first = True
|
219
|
+
self.run_input_handlers_next_turn = False
|
216
220
|
|
217
221
|
def set_user_data(self, key: str, value: Any):
|
218
222
|
"""Sets user data in the session."""
|
@@ -236,6 +240,10 @@ class Agent:
|
|
236
240
|
"""Sets the addon prompt in the session."""
|
237
241
|
self.session.set_addon_prompt(addon_prompt)
|
238
242
|
|
243
|
+
def set_run_input_handlers_next_turn(self, value: bool):
|
244
|
+
"""Sets the flag to run input handlers on the next turn."""
|
245
|
+
self.run_input_handlers_next_turn = value
|
246
|
+
|
239
247
|
def set_after_tool_call_cb(self, cb: Callable[[Any], None]): # type: ignore
|
240
248
|
"""设置工具调用后回调函数。
|
241
249
|
|
@@ -264,7 +272,9 @@ class Agent:
|
|
264
272
|
return handler
|
265
273
|
return None
|
266
274
|
|
267
|
-
def _call_model(
|
275
|
+
def _call_model(
|
276
|
+
self, message: str, need_complete: bool = False, run_input_handlers: bool = True
|
277
|
+
) -> str:
|
268
278
|
"""调用AI模型并实现重试逻辑
|
269
279
|
|
270
280
|
参数:
|
@@ -280,10 +290,11 @@ class Agent:
|
|
280
290
|
3. 会自动添加附加提示
|
281
291
|
4. 会检查并处理上下文长度限制
|
282
292
|
"""
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
293
|
+
if run_input_handlers:
|
294
|
+
for handler in self.input_handler:
|
295
|
+
message, need_return = handler(message, self)
|
296
|
+
if need_return:
|
297
|
+
return message
|
287
298
|
|
288
299
|
if self.session.addon_prompt:
|
289
300
|
message += f"\n\n{self.session.addon_prompt}"
|
@@ -478,12 +489,20 @@ class Agent:
|
|
478
489
|
try:
|
479
490
|
set_agent(self.name, self)
|
480
491
|
|
492
|
+
run_input_handlers = True
|
481
493
|
while True:
|
494
|
+
if self.run_input_handlers_next_turn:
|
495
|
+
run_input_handlers = True
|
496
|
+
self.run_input_handlers_next_turn = False
|
497
|
+
|
482
498
|
if self.first:
|
483
499
|
self._first_run()
|
484
500
|
try:
|
485
|
-
current_response = self._call_model(
|
501
|
+
current_response = self._call_model(
|
502
|
+
self.session.prompt, True, run_input_handlers
|
503
|
+
)
|
486
504
|
self.session.prompt = ""
|
505
|
+
run_input_handlers = False
|
487
506
|
|
488
507
|
if get_interrupt():
|
489
508
|
set_interrupt(False)
|
@@ -491,6 +510,7 @@ class Agent:
|
|
491
510
|
f"模型交互期间被中断,请输入用户干预信息:"
|
492
511
|
)
|
493
512
|
if user_input:
|
513
|
+
run_input_handlers = True
|
494
514
|
# 如果有工具调用且用户确认继续,则将干预信息和工具执行结果拼接为prompt
|
495
515
|
if any(
|
496
516
|
handler.can_handle(current_response)
|
@@ -502,6 +522,7 @@ class Agent:
|
|
502
522
|
self.session.prompt = (
|
503
523
|
f"{user_input}\n\n{current_response}"
|
504
524
|
)
|
525
|
+
run_input_handlers = False
|
505
526
|
continue
|
506
527
|
self.session.prompt += f"{user_input}"
|
507
528
|
continue
|
@@ -529,6 +550,7 @@ class Agent:
|
|
529
550
|
|
530
551
|
if user_input:
|
531
552
|
self.session.prompt = user_input
|
553
|
+
run_input_handlers = True
|
532
554
|
continue
|
533
555
|
|
534
556
|
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",
|
@@ -122,6 +125,11 @@ def main() -> None:
|
|
122
125
|
type=str,
|
123
126
|
help="Directly input task content from command line",
|
124
127
|
)
|
128
|
+
parser.add_argument(
|
129
|
+
"--model_group",
|
130
|
+
type=str,
|
131
|
+
help="Model group to use, overriding config",
|
132
|
+
)
|
125
133
|
parser.add_argument("-f", "--config", type=str, help="Path to custom config file")
|
126
134
|
parser.add_argument(
|
127
135
|
"--restore-session",
|
@@ -129,44 +137,91 @@ def main() -> None:
|
|
129
137
|
help="Restore session from .jarvis/saved_session.json",
|
130
138
|
default=False,
|
131
139
|
)
|
132
|
-
|
133
|
-
|
134
|
-
"欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config
|
140
|
+
parser.add_argument(
|
141
|
+
"-e", "--edit", action="store_true", help="Edit the configuration file"
|
135
142
|
)
|
143
|
+
return parser.parse_args()
|
136
144
|
|
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
145
|
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
146
|
+
def _handle_edit_mode(args: argparse.Namespace) -> None:
|
147
|
+
"""If edit flag is set, open config file in editor and exit."""
|
148
|
+
if not args.edit:
|
149
|
+
return
|
150
|
+
|
151
|
+
config_file_path = (
|
152
|
+
Path(args.config)
|
153
|
+
if args.config
|
154
|
+
else Path(os.path.expanduser("~/.jarvis/config.yaml"))
|
155
|
+
)
|
156
|
+
editors = ["nvim", "vim", "vi"]
|
157
|
+
editor = next((e for e in editors if shutil.which(e)), None)
|
152
158
|
|
153
|
-
|
154
|
-
|
155
|
-
|
159
|
+
if editor:
|
160
|
+
try:
|
161
|
+
subprocess.run([editor, str(config_file_path)], check=True)
|
156
162
|
sys.exit(0)
|
163
|
+
except (subprocess.CalledProcessError, FileNotFoundError) as e:
|
164
|
+
PrettyOutput.print(f"Failed to open editor: {e}", OutputType.ERROR)
|
165
|
+
sys.exit(1)
|
166
|
+
else:
|
167
|
+
PrettyOutput.print(
|
168
|
+
"No suitable editor found (nvim, vim, vi).", OutputType.ERROR
|
169
|
+
)
|
170
|
+
sys.exit(1)
|
157
171
|
|
158
|
-
if agent.first:
|
159
|
-
tasks = _load_tasks()
|
160
|
-
if tasks and (selected_task := _select_task(tasks)):
|
161
|
-
PrettyOutput.print(f"开始执行任务: \n{selected_task}", OutputType.INFO)
|
162
|
-
agent.run(selected_task)
|
163
|
-
sys.exit(0)
|
164
172
|
|
165
|
-
|
166
|
-
|
167
|
-
|
173
|
+
def _initialize_agent(args: argparse.Namespace) -> Agent:
|
174
|
+
"""Initialize the agent and restore session if requested."""
|
175
|
+
agent = Agent(
|
176
|
+
system_prompt=origin_agent_system_prompt,
|
177
|
+
llm_type=args.llm_type,
|
178
|
+
model_group=args.model_group,
|
179
|
+
input_handler=[shell_input_handler, builtin_input_handler],
|
180
|
+
output_handler=[ToolRegistry()], # type: ignore
|
181
|
+
need_summary=False,
|
182
|
+
)
|
183
|
+
|
184
|
+
# 尝试恢复会话
|
185
|
+
if args.restore_session:
|
186
|
+
if agent.restore_session():
|
187
|
+
PrettyOutput.print("会话已成功恢复。", OutputType.SUCCESS)
|
188
|
+
else:
|
189
|
+
PrettyOutput.print("无法恢复会话。", OutputType.WARNING)
|
190
|
+
return agent
|
191
|
+
|
192
|
+
|
193
|
+
def _get_and_run_task(agent: Agent, task_content: Optional[str] = None) -> None:
|
194
|
+
"""Get task from various sources and run it."""
|
195
|
+
# 优先处理命令行直接传入的任务
|
196
|
+
if task_content:
|
197
|
+
agent.run(task_content)
|
168
198
|
sys.exit(0)
|
169
199
|
|
200
|
+
if agent.first:
|
201
|
+
tasks = _load_tasks()
|
202
|
+
if tasks and (selected_task := _select_task(tasks)):
|
203
|
+
PrettyOutput.print(f"开始执行任务: \n{selected_task}", OutputType.INFO)
|
204
|
+
agent.run(selected_task)
|
205
|
+
sys.exit(0)
|
206
|
+
|
207
|
+
user_input = get_multiline_input("请输入你的任务(输入空行退出):")
|
208
|
+
if user_input:
|
209
|
+
agent.run(user_input)
|
210
|
+
sys.exit(0)
|
211
|
+
|
212
|
+
|
213
|
+
def main() -> None:
|
214
|
+
"""Main function for Jarvis AI assistant."""
|
215
|
+
args = _parse_args()
|
216
|
+
_handle_edit_mode(args)
|
217
|
+
|
218
|
+
init_env(
|
219
|
+
"欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config
|
220
|
+
)
|
221
|
+
|
222
|
+
try:
|
223
|
+
agent = _initialize_agent(args)
|
224
|
+
_get_and_run_task(agent, args.task)
|
170
225
|
except Exception as err: # pylint: disable=broad-except
|
171
226
|
PrettyOutput.print(f"初始化错误: {str(err)}", OutputType.ERROR)
|
172
227
|
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:
|
@@ -50,10 +52,17 @@ def main():
|
|
50
52
|
choices=["normal", "thinking"],
|
51
53
|
help="LLM type to use, overriding config",
|
52
54
|
)
|
55
|
+
parser.add_argument(
|
56
|
+
"--model_group",
|
57
|
+
type=str,
|
58
|
+
help="Model group to use, overriding config",
|
59
|
+
)
|
53
60
|
args = parser.parse_args()
|
54
61
|
|
55
62
|
# Initialize environment
|
56
|
-
init_env(
|
63
|
+
init_env(
|
64
|
+
"欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config
|
65
|
+
)
|
57
66
|
|
58
67
|
# Load configuration
|
59
68
|
config = load_config(args.agent_definition) if args.agent_definition else {}
|
@@ -61,6 +70,8 @@ def main():
|
|
61
70
|
# Override config with command-line arguments if provided
|
62
71
|
if args.llm_type:
|
63
72
|
config["llm_type"] = args.llm_type
|
73
|
+
if args.model_group:
|
74
|
+
config["model_group"] = args.model_group
|
64
75
|
|
65
76
|
# Create and run agent
|
66
77
|
try:
|
@@ -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,
|
@@ -44,6 +47,7 @@ class CodeAgent:
|
|
44
47
|
def __init__(
|
45
48
|
self,
|
46
49
|
llm_type: str = "normal",
|
50
|
+
model_group: Optional[str] = None,
|
47
51
|
need_summary: bool = True,
|
48
52
|
):
|
49
53
|
self.root_dir = os.getcwd()
|
@@ -54,7 +58,6 @@ class CodeAgent:
|
|
54
58
|
"search_web",
|
55
59
|
"ask_user",
|
56
60
|
"read_code",
|
57
|
-
"methodology",
|
58
61
|
"rewrite_file",
|
59
62
|
]
|
60
63
|
)
|
@@ -116,8 +119,9 @@ class CodeAgent:
|
|
116
119
|
system_prompt=code_system_prompt,
|
117
120
|
name="CodeAgent",
|
118
121
|
auto_complete=False,
|
119
|
-
output_handler=[tool_registry, EditFileHandler()],
|
122
|
+
output_handler=[tool_registry, EditFileHandler()], # type: ignore
|
120
123
|
llm_type=llm_type,
|
124
|
+
model_group=model_group,
|
121
125
|
input_handler=[shell_input_handler, builtin_input_handler],
|
122
126
|
need_summary=need_summary,
|
123
127
|
use_methodology=False, # 禁用方法论
|
@@ -409,6 +413,11 @@ def main() -> None:
|
|
409
413
|
choices=["normal", "thinking"],
|
410
414
|
help="LLM type to use",
|
411
415
|
)
|
416
|
+
parser.add_argument(
|
417
|
+
"--model_group",
|
418
|
+
type=str,
|
419
|
+
help="Model group to use, overriding config",
|
420
|
+
)
|
412
421
|
parser.add_argument(
|
413
422
|
"-r", "--requirement", type=str, help="Requirement to process", default=None
|
414
423
|
)
|
@@ -425,7 +434,11 @@ def main() -> None:
|
|
425
434
|
PrettyOutput.print(f"当前目录: {git_dir}", OutputType.INFO)
|
426
435
|
|
427
436
|
try:
|
428
|
-
agent = CodeAgent(
|
437
|
+
agent = CodeAgent(
|
438
|
+
llm_type=args.llm_type,
|
439
|
+
model_group=args.model_group,
|
440
|
+
need_summary=False,
|
441
|
+
)
|
429
442
|
|
430
443
|
# 尝试恢复会话
|
431
444
|
if args.restore_session:
|
@@ -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 = {
|
@@ -3,12 +3,13 @@ import os
|
|
3
3
|
import re
|
4
4
|
import subprocess
|
5
5
|
import tempfile
|
6
|
-
from typing import Any, Dict, List
|
6
|
+
from typing import Any, Dict, List, Optional
|
7
7
|
|
8
8
|
from jarvis.jarvis_agent import Agent
|
9
9
|
from jarvis.jarvis_code_analysis.checklists.loader import get_language_checklist
|
10
10
|
from jarvis.jarvis_platform.registry import PlatformRegistry
|
11
11
|
from jarvis.jarvis_tools.read_code import ReadCodeTool
|
12
|
+
from jarvis.jarvis_utils.globals import get_agent, current_agent_name
|
12
13
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
13
14
|
from jarvis.jarvis_utils.tag import ct, ot
|
14
15
|
from jarvis.jarvis_utils.utils import init_env, is_context_overflow
|
@@ -261,7 +262,9 @@ class CodeReviewTool:
|
|
261
262
|
checklist = get_language_checklist(language)
|
262
263
|
return checklist if checklist else ""
|
263
264
|
|
264
|
-
def execute(
|
265
|
+
def execute(
|
266
|
+
self, args: Dict[str, Any], agent: Optional["Agent"] = None
|
267
|
+
) -> Dict[str, Any]:
|
265
268
|
try:
|
266
269
|
review_type = args.get("review_type", "current").strip()
|
267
270
|
root_dir = args.get("root_dir", ".")
|
@@ -570,9 +573,17 @@ class CodeReviewTool:
|
|
570
573
|
|
571
574
|
tool_registry = ToolRegistry()
|
572
575
|
tool_registry.dont_use_tools(["code_review"])
|
576
|
+
|
577
|
+
# Use the provided agent's model_group or get it from globals
|
578
|
+
calling_agent = agent or get_agent(current_agent_name)
|
579
|
+
model_group = None
|
580
|
+
if calling_agent and hasattr(calling_agent, "model") and calling_agent.model:
|
581
|
+
model_group = calling_agent.model.model_group
|
582
|
+
|
573
583
|
agent = Agent(
|
574
584
|
system_prompt=system_prompt,
|
575
585
|
name="Code Review Agent",
|
586
|
+
model_group=model_group,
|
576
587
|
summary_prompt=f"""<code_review_report>
|
577
588
|
<overview>
|
578
589
|
# 整体评估
|
@@ -675,7 +686,7 @@ class CodeReviewTool:
|
|
675
686
|
|
676
687
|
try:
|
677
688
|
# Check if content is too large
|
678
|
-
is_large_content = is_context_overflow(diff_output)
|
689
|
+
is_large_content = is_context_overflow(diff_output, model_group)
|
679
690
|
|
680
691
|
# Upload the file to the agent's model
|
681
692
|
if is_large_content:
|
@@ -141,6 +141,47 @@
|
|
141
141
|
"description": "思考操作模型名称",
|
142
142
|
"default": "deep_seek"
|
143
143
|
},
|
144
|
+
"JARVIS_MODEL_GROUP": {
|
145
|
+
"type": "string",
|
146
|
+
"description": "选择一个预定义的模型组"
|
147
|
+
},
|
148
|
+
"JARVIS_MODEL_GROUPS": {
|
149
|
+
"type": "array",
|
150
|
+
"description": "预定义的模型配置组",
|
151
|
+
"items": {
|
152
|
+
"type": "object",
|
153
|
+
"additionalProperties": {
|
154
|
+
"type": "object",
|
155
|
+
"properties": {
|
156
|
+
"JARVIS_PLATFORM": {
|
157
|
+
"type": "string"
|
158
|
+
},
|
159
|
+
"JARVIS_MODEL": {
|
160
|
+
"type": "string"
|
161
|
+
},
|
162
|
+
"JARVIS_THINKING_PLATFORM": {
|
163
|
+
"type": "string"
|
164
|
+
},
|
165
|
+
"JARVIS_THINKING_MODEL": {
|
166
|
+
"type": "string"
|
167
|
+
},
|
168
|
+
"JARVIS_MAX_TOKEN_COUNT": {
|
169
|
+
"type": "number"
|
170
|
+
},
|
171
|
+
"JARVIS_MAX_INPUT_TOKEN_COUNT": {
|
172
|
+
"type": "number"
|
173
|
+
},
|
174
|
+
"JARVIS_MAX_BIG_CONTENT_SIZE": {
|
175
|
+
"type": "number"
|
176
|
+
}
|
177
|
+
},
|
178
|
+
"required": [
|
179
|
+
"JARVIS_PLATFORM",
|
180
|
+
"JARVIS_MODEL"
|
181
|
+
]
|
182
|
+
}
|
183
|
+
}
|
184
|
+
},
|
144
185
|
"JARVIS_EXECUTE_TOOL_CONFIRM": {
|
145
186
|
"type": "boolean",
|
146
187
|
"description": "执行工具前是否需要确认",
|
@@ -16,6 +16,7 @@ from jarvis.jarvis_utils.git_utils import (
|
|
16
16
|
find_git_root_and_cd,
|
17
17
|
has_uncommitted_changes,
|
18
18
|
)
|
19
|
+
from jarvis.jarvis_utils.globals import get_agent, current_agent_name
|
19
20
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
20
21
|
from jarvis.jarvis_utils.tag import ct, ot
|
21
22
|
from jarvis.jarvis_utils.utils import init_env, is_context_overflow
|
@@ -162,11 +163,17 @@ commit信息
|
|
162
163
|
"""
|
163
164
|
|
164
165
|
# 获取模型并尝试上传文件
|
165
|
-
|
166
|
+
agent = get_agent(current_agent_name)
|
167
|
+
if agent:
|
168
|
+
platform = agent.model
|
169
|
+
model_group = agent.model.model_group
|
170
|
+
else:
|
171
|
+
platform = PlatformRegistry().get_normal_platform()
|
172
|
+
model_group = None
|
166
173
|
upload_success = False
|
167
174
|
|
168
175
|
# Check if content is too large
|
169
|
-
is_large_content = is_context_overflow(diff)
|
176
|
+
is_large_content = is_context_overflow(diff, model_group)
|
170
177
|
|
171
178
|
if is_large_content:
|
172
179
|
if not platform.support_upload_files():
|
@@ -2,7 +2,7 @@
|
|
2
2
|
import json
|
3
3
|
import threading
|
4
4
|
import time
|
5
|
-
from typing import Any, Callable, Dict, List
|
5
|
+
from typing import Any, Callable, Dict, List, Optional
|
6
6
|
from urllib.parse import parse_qs, urlencode, urljoin
|
7
7
|
|
8
8
|
import requests
|
@@ -46,10 +46,10 @@ class SSEMcpClient(McpClient):
|
|
46
46
|
self.session.headers.update(extra_headers)
|
47
47
|
|
48
48
|
# SSE相关属性
|
49
|
-
self.sse_response = None
|
50
|
-
self.sse_thread = None
|
51
|
-
self.messages_endpoint = None
|
52
|
-
self.session_id = None
|
49
|
+
self.sse_response: Optional[requests.Response] = None
|
50
|
+
self.sse_thread: Optional[threading.Thread] = None
|
51
|
+
self.messages_endpoint: Optional[str] = None
|
52
|
+
self.session_id: Optional[str] = None
|
53
53
|
self.pending_requests = {} # 存储等待响应的请求 {id: Event}
|
54
54
|
self.request_results = {} # 存储请求结果 {id: result}
|
55
55
|
self.notification_handlers = {}
|
@@ -123,13 +123,15 @@ class SSEMcpClient(McpClient):
|
|
123
123
|
self.sse_response = self.session.get(
|
124
124
|
sse_url, stream=True, headers=sse_headers, timeout=30
|
125
125
|
)
|
126
|
-
self.sse_response
|
126
|
+
if self.sse_response:
|
127
|
+
self.sse_response.raise_for_status()
|
127
128
|
|
128
129
|
# 启动事件处理线程
|
129
130
|
self.sse_thread = threading.Thread(
|
130
131
|
target=self._process_sse_events, daemon=True
|
131
132
|
)
|
132
|
-
self.sse_thread
|
133
|
+
if self.sse_thread:
|
134
|
+
self.sse_thread.start()
|
133
135
|
|
134
136
|
except Exception as e:
|
135
137
|
PrettyOutput.print(f"SSE连接失败: {str(e)}", OutputType.ERROR)
|
@@ -2,7 +2,7 @@
|
|
2
2
|
import json
|
3
3
|
import os
|
4
4
|
import subprocess
|
5
|
-
from typing import Any, Dict, List
|
5
|
+
from typing import Any, Dict, List, Optional
|
6
6
|
|
7
7
|
from jarvis.jarvis_mcp import McpClient
|
8
8
|
from jarvis.jarvis_utils.output import OutputType, PrettyOutput
|
@@ -17,7 +17,7 @@ class StdioMcpClient(McpClient):
|
|
17
17
|
|
18
18
|
def __init__(self, config: Dict[str, Any]):
|
19
19
|
self.config = config
|
20
|
-
self.process = None
|
20
|
+
self.process: Optional[subprocess.Popen] = None
|
21
21
|
self.protocol_version = "2025-03-26" # MCP协议版本
|
22
22
|
self._start_process()
|
23
23
|
self._initialize()
|