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.
Files changed (32) hide show
  1. jarvis/__init__.py +1 -1
  2. jarvis/jarvis_agent/__init__.py +33 -11
  3. jarvis/jarvis_agent/jarvis.py +87 -32
  4. jarvis/jarvis_agent/main.py +13 -2
  5. jarvis/jarvis_code_agent/code_agent.py +17 -4
  6. jarvis/jarvis_code_analysis/checklists/loader.py +20 -6
  7. jarvis/jarvis_code_analysis/code_review.py +14 -3
  8. jarvis/jarvis_data/config_schema.json +41 -0
  9. jarvis/jarvis_git_utils/git_commiter.py +9 -2
  10. jarvis/jarvis_mcp/sse_mcp_client.py +9 -7
  11. jarvis/jarvis_mcp/stdio_mcp_client.py +2 -2
  12. jarvis/jarvis_platform/base.py +28 -13
  13. jarvis/jarvis_platform_manager/main.py +18 -6
  14. jarvis/jarvis_rag/llm_interface.py +1 -3
  15. jarvis/jarvis_smart_shell/main.py +18 -12
  16. jarvis/jarvis_tools/ask_user.py +1 -0
  17. jarvis/jarvis_tools/generate_new_tool.py +1 -0
  18. jarvis/jarvis_tools/registry.py +17 -9
  19. jarvis/jarvis_tools/search_web.py +19 -9
  20. jarvis/jarvis_utils/builtin_replace_map.py +0 -1
  21. jarvis/jarvis_utils/config.py +80 -21
  22. jarvis/jarvis_utils/git_utils.py +2 -2
  23. jarvis/jarvis_utils/globals.py +17 -11
  24. jarvis/jarvis_utils/methodology.py +37 -23
  25. jarvis/jarvis_utils/output.py +2 -2
  26. jarvis/jarvis_utils/utils.py +138 -3
  27. {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/METADATA +49 -12
  28. {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/RECORD +32 -32
  29. {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/WHEEL +0 -0
  30. {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/entry_points.txt +0 -0
  31. {jarvis_ai_assistant-0.1.224.dist-info → jarvis_ai_assistant-0.2.0.dist-info}/licenses/LICENSE +0 -0
  32. {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
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Jarvis AI Assistant"""
3
3
 
4
- __version__ = "0.1.224"
4
+ __version__ = "0.2.0"
@@ -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(self, message: str, need_complete: bool = False) -> str:
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
- for handler in self.input_handler:
284
- message, need_return = handler(message, self)
285
- if need_return:
286
- return message
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(self.session.prompt, True)
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:
@@ -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 typing import Dict
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 main() -> None:
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
- args = parser.parse_args()
133
- init_env(
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
- if args.restore_session:
148
- if agent.restore_session():
149
- PrettyOutput.print("会话已成功恢复。", OutputType.SUCCESS)
150
- else:
151
- PrettyOutput.print("无法恢复会话。", OutputType.WARNING)
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
- if args.task:
155
- agent.run(args.task)
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
- user_input = get_multiline_input("请输入你的任务(输入空行退出):")
166
- if user_input:
167
- agent.run(user_input)
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)
@@ -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(f"配置文件 {config_path} 不存在,使用默认配置", OutputType.WARNING)
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("欢迎使用 Jarvis AI 助手,您的智能助理已准备就绪!", config_file=args.config)
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 is_confirm_before_apply_patch, is_enable_static_analysis
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(llm_type=args.llm_type, need_summary=False)
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 (c_cpp, csharp, data_format,
9
- devops, docs, go,
10
- infrastructure, java,
11
- javascript, kotlin, php,
12
- python, ruby, rust, shell,
13
- sql, swift, web)
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(self, args: Dict[str, Any]) -> Dict[str, Any]:
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
- platform = PlatformRegistry().get_normal_platform()
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 # 从SSE连接获取的会话ID
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.raise_for_status()
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.start()
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()