jarvis-ai-assistant 0.1.150__py3-none-any.whl → 0.1.152__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.

Potentially problematic release.


This version of jarvis-ai-assistant might be problematic. Click here for more details.

@@ -10,13 +10,17 @@ import yaml
10
10
  from jarvis.jarvis_agent.output_handler import OutputHandler
11
11
  from jarvis.jarvis_platform.registry import PlatformRegistry
12
12
  from jarvis.jarvis_tools.base import Tool
13
- from jarvis.jarvis_utils.config import INPUT_WINDOW_REVERSE_SIZE, get_max_input_token_count, get_data_dir
13
+ from jarvis.jarvis_utils.config import (
14
+ INPUT_WINDOW_REVERSE_SIZE,
15
+ get_max_input_token_count,
16
+ get_data_dir,
17
+ )
14
18
  from jarvis.jarvis_utils.embedding import get_context_token_count
15
19
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
16
20
  from jarvis.jarvis_utils.utils import ct, ot, init_env
17
- from jarvis.jarvis_mcp.local_mcp_client import LocalMcpClient
18
- from jarvis.jarvis_mcp.remote_mcp_client import RemoteMcpClient
19
-
21
+ from jarvis.jarvis_mcp.stdio_mcp_client import StdioMcpClient
22
+ from jarvis.jarvis_mcp.sse_mcp_client import SSEMcpClient
23
+ from jarvis.jarvis_mcp import McpClient
20
24
 
21
25
 
22
26
  tool_call_help = f"""
@@ -81,6 +85,7 @@ arguments:
81
85
  - 在没有所需信息的情况下继续
82
86
  """
83
87
 
88
+
84
89
  class ToolRegistry(OutputHandler):
85
90
 
86
91
  def name(self) -> str:
@@ -102,19 +107,22 @@ class ToolRegistry(OutputHandler):
102
107
 
103
108
  # 生成格式化的YAML参数
104
109
  yaml_params = yaml.dump(
105
- tool['parameters'],
110
+ tool["parameters"],
106
111
  allow_unicode=True,
107
112
  indent=4,
108
113
  sort_keys=False,
109
- width=120 # 增加行宽限制
114
+ width=120, # 增加行宽限制
110
115
  )
111
116
 
112
117
  # 添加缩进并移除尾部空格
113
- for line in yaml_params.split('\n'):
118
+ for line in yaml_params.split("\n"):
114
119
  tools_prompt += f" {line.rstrip()}\n"
115
120
 
116
121
  except yaml.YAMLError as e:
117
- PrettyOutput.print(f"工具 {tool['name']} 参数序列化失败: {str(e)}", OutputType.ERROR)
122
+ PrettyOutput.print(
123
+ f"工具 {tool['name']} 参数序列化失败: {str(e)}",
124
+ OutputType.ERROR,
125
+ )
118
126
  continue
119
127
 
120
128
  tools_prompt += tool_call_help.rstrip() # 移除帮助文本尾部空格
@@ -134,30 +142,37 @@ class ToolRegistry(OutputHandler):
134
142
  self._load_builtin_tools()
135
143
  self._load_external_tools()
136
144
  self._load_mcp_tools()
137
- self.max_input_token_count = get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE
145
+ self.max_input_token_count = (
146
+ get_max_input_token_count() - INPUT_WINDOW_REVERSE_SIZE
147
+ )
138
148
 
139
149
  def use_tools(self, name: List[str]) -> None:
140
150
  """使用指定工具
141
-
151
+
142
152
  参数:
143
153
  name: 要使用的工具名称列表
144
154
  """
145
155
  missing_tools = [tool_name for tool_name in name if tool_name not in self.tools]
146
156
  if missing_tools:
147
- PrettyOutput.print(f"工具 {missing_tools} 不存在,可用的工具有: {', '.join(self.tools.keys())}", OutputType.WARNING)
157
+ PrettyOutput.print(
158
+ f"工具 {missing_tools} 不存在,可用的工具有: {', '.join(self.tools.keys())}",
159
+ OutputType.WARNING,
160
+ )
148
161
  self.tools = {tool_name: self.tools[tool_name] for tool_name in name}
149
162
 
150
163
  def dont_use_tools(self, names: List[str]) -> None:
151
164
  """从注册表中移除指定工具
152
-
165
+
153
166
  参数:
154
167
  names: 要移除的工具名称列表
155
168
  """
156
- self.tools = {name: tool for name, tool in self.tools.items() if name not in names}
169
+ self.tools = {
170
+ name: tool for name, tool in self.tools.items() if name not in names
171
+ }
157
172
 
158
173
  def _load_mcp_tools(self) -> None:
159
174
  """从jarvis_data/tools/mcp加载工具"""
160
- mcp_tools_dir = Path(get_data_dir()) / 'mcp'
175
+ mcp_tools_dir = Path(get_data_dir()) / "mcp"
161
176
  if not mcp_tools_dir.exists():
162
177
  return
163
178
 
@@ -179,7 +194,7 @@ class ToolRegistry(OutputHandler):
179
194
 
180
195
  def _load_external_tools(self) -> None:
181
196
  """从jarvis_data/tools加载外部工具"""
182
- external_tools_dir = Path(get_data_dir()) / 'tools'
197
+ external_tools_dir = Path(get_data_dir()) / "tools"
183
198
  if not external_tools_dir.exists():
184
199
  return
185
200
 
@@ -193,7 +208,7 @@ class ToolRegistry(OutputHandler):
193
208
 
194
209
  def register_mcp_tool_by_file(self, file_path: str) -> bool:
195
210
  """从指定文件加载并注册工具
196
-
211
+
197
212
  参数:
198
213
  file_path: 工具文件的路径
199
214
 
@@ -201,88 +216,145 @@ class ToolRegistry(OutputHandler):
201
216
  bool: 工具是否加载成功
202
217
  """
203
218
  try:
204
- config = yaml.safe_load(open(file_path, 'r', encoding='utf-8'))
205
- if 'type' not in config:
219
+ config = yaml.safe_load(open(file_path, "r", encoding="utf-8"))
220
+ if "type" not in config:
206
221
  PrettyOutput.print(f"文件 {file_path} 缺少type字段", OutputType.WARNING)
207
222
  return False
208
- if config['type'] == 'local':
209
- if 'command' not in config:
210
- PrettyOutput.print(f"文件 {file_path} 缺少command字段", OutputType.WARNING)
211
- return False
212
-
213
- # 创建本地MCP客户端
214
- mcp_client = LocalMcpClient(config)
215
-
216
- # 获取工具信息
217
- tools = mcp_client.get_tool_list()
218
- if not tools:
219
- PrettyOutput.print(f"从 {file_path} 获取工具列表失败", OutputType.WARNING)
220
- return False
221
-
222
- # 注册每个工具
223
- for tool in tools:
224
- def create_local_execute_func(tool_name: str, client: LocalMcpClient):
225
- def execute(arguments: Dict[str, Any]) -> Dict[str, Any]:
226
- args = arguments.copy()
227
- args.pop('agent', None)
228
- args.pop('want', None)
229
- ret = client.execute(tool_name, args)
230
- PrettyOutput.print(f"MCP {tool_name} 执行结果:\n{yaml.safe_dump(ret)}", OutputType.TOOL)
231
- return ret
232
- return execute
233
-
234
- # 注册工具
235
- self.register_tool(
236
- name=tool['name'],
237
- description=tool['description'],
238
- parameters=tool['parameters'],
239
- func=create_local_execute_func(tool['name'], mcp_client)
223
+
224
+ # 检查enable标志
225
+ if not config.get("enable", True):
226
+ PrettyOutput.print(
227
+ f"文件 {file_path} 已禁用(enable=false),跳过注册", OutputType.INFO
228
+ )
229
+ return False
230
+
231
+ name = config.get("name", Path(file_path).stem)
232
+
233
+ # 注册资源工具
234
+ def create_resource_list_func(client: McpClient):
235
+ def execute(arguments: Dict[str, Any]) -> Dict[str, Any]:
236
+ args = arguments.copy()
237
+ args.pop("agent", None)
238
+ args.pop("want", None)
239
+ ret = client.get_resource_list()
240
+ PrettyOutput.print(
241
+ f"MCP {name} 资源列表:\n{yaml.safe_dump(ret)}", OutputType.TOOL
242
+ )
243
+ return {
244
+ "success": True,
245
+ "stdout": yaml.safe_dump(ret),
246
+ "stderr": "",
247
+ }
248
+
249
+ return execute
250
+
251
+ def create_resource_get_func(client: McpClient):
252
+ def execute(arguments: Dict[str, Any]) -> Dict[str, Any]:
253
+ args = arguments.copy()
254
+ args.pop("agent", None)
255
+ args.pop("want", None)
256
+ if "uri" not in args:
257
+ return {
258
+ "success": False,
259
+ "stdout": "",
260
+ "stderr": "缺少必需的uri参数",
261
+ }
262
+ ret = client.get_resource(args["uri"])
263
+ PrettyOutput.print(
264
+ f"MCP {name} 获取资源:\n{yaml.safe_dump(ret)}", OutputType.TOOL
265
+ )
266
+ return ret
267
+
268
+ return execute
269
+
270
+ def create_mcp_execute_func(tool_name: str, client: McpClient):
271
+ def execute(arguments: Dict[str, Any]) -> Dict[str, Any]:
272
+ args = arguments.copy()
273
+ args.pop("agent", None)
274
+ args.pop("want", None)
275
+ ret = client.execute(tool_name, args)
276
+ PrettyOutput.print(
277
+ f"MCP {name} {tool_name} 执行结果:\n{yaml.safe_dump(ret)}",
278
+ OutputType.TOOL,
279
+ )
280
+ return ret
281
+
282
+ return execute
283
+
284
+ if config["type"] == "stdio":
285
+ if "command" not in config:
286
+ PrettyOutput.print(
287
+ f"文件 {file_path} 缺少command字段", OutputType.WARNING
240
288
  )
241
-
242
- return True
243
-
244
- elif config['type'] == 'remote':
245
- if 'base_url' not in config:
246
- PrettyOutput.print(f"文件 {file_path} 缺少base_url字段", OutputType.WARNING)
247
- return False
248
-
249
- # 创建远程MCP客户端
250
- mcp_client = RemoteMcpClient(config)
251
-
252
- # 获取工具信息
253
- tools = mcp_client.get_tool_list()
254
- if not tools:
255
- PrettyOutput.print(f"从 {file_path} 获取工具列表失败", OutputType.WARNING)
256
289
  return False
257
-
258
- # 注册每个工具
259
- for tool in tools:
260
- def create_remote_execute_func(tool_name: str, client: RemoteMcpClient):
261
- def execute(arguments: Dict[str, Any]) -> Dict[str, Any]:
262
- args = arguments.copy()
263
- args.pop('agent', None)
264
- args.pop('want', None)
265
- ret = client.execute(tool_name, args)
266
- PrettyOutput.print(f"MCP {tool_name} 执行结果:\n{yaml.safe_dump(ret)}", OutputType.TOOL)
267
- return ret
268
- return execute
269
-
270
- # 注册工具
271
- self.register_tool(
272
- name=tool['name'],
273
- description=tool['description'],
274
- parameters=tool['parameters'],
275
- func=create_remote_execute_func(tool['name'], mcp_client)
290
+ elif config["type"] == "sse":
291
+ if "base_url" not in config:
292
+ PrettyOutput.print(
293
+ f"文件 {file_path} 缺少base_url字段", OutputType.WARNING
276
294
  )
277
-
278
- return True
295
+ return False
279
296
  else:
280
- PrettyOutput.print(f"文件 {file_path} 类型错误: {config['type']}", OutputType.WARNING)
297
+ PrettyOutput.print(
298
+ f"文件 {file_path} 类型错误: {config['type']}", OutputType.WARNING
299
+ )
300
+ return False
301
+
302
+ # 创建MCP客户端
303
+ mcp_client: McpClient = (
304
+ StdioMcpClient(config)
305
+ if config["type"] == "stdio"
306
+ else SSEMcpClient(config)
307
+ )
308
+
309
+ # 获取工具信息
310
+ tools = mcp_client.get_tool_list()
311
+ if not tools:
312
+ PrettyOutput.print(
313
+ f"从 {file_path} 获取工具列表失败", OutputType.WARNING
314
+ )
281
315
  return False
316
+
317
+ # 注册每个工具
318
+ for tool in tools:
319
+
320
+ # 注册工具
321
+ self.register_tool(
322
+ name=f"{name}.tool_call.{tool['name']}",
323
+ description=tool["description"],
324
+ parameters=tool["parameters"],
325
+ func=create_mcp_execute_func(tool["name"], mcp_client),
326
+ )
327
+
328
+ # 注册资源列表工具
329
+ self.register_tool(
330
+ name=f"{name}.resource.get_resource_list",
331
+ description=f"获取{name}MCP服务器上的资源列表",
332
+ parameters={"type": "object", "properties": {}, "required": []},
333
+ func=create_resource_list_func(mcp_client),
334
+ )
335
+
336
+ # 注册获取资源工具
337
+ self.register_tool(
338
+ name=f"{name}.resource.get_resource",
339
+ description=f"获取{name}MCP服务器上的指定资源",
340
+ parameters={
341
+ "type": "object",
342
+ "properties": {
343
+ "uri": {"type": "string", "description": "资源的URI标识符"}
344
+ },
345
+ "required": ["uri"],
346
+ },
347
+ func=create_resource_get_func(mcp_client),
348
+ )
349
+
350
+ return True
351
+
282
352
  except Exception as e:
283
- PrettyOutput.print(f"文件 {file_path} 加载失败: {str(e)}", OutputType.WARNING)
353
+ PrettyOutput.print(
354
+ f"文件 {file_path} 加载失败: {str(e)}", OutputType.WARNING
355
+ )
284
356
  return False
285
-
357
+
286
358
  def register_tool_by_file(self, file_path: str) -> bool:
287
359
  """从指定文件加载并注册工具
288
360
 
@@ -312,12 +384,14 @@ class ToolRegistry(OutputHandler):
312
384
  for item_name in dir(module):
313
385
  item = getattr(module, item_name)
314
386
  # 检查是否是类并具有必要属性
315
- if (isinstance(item, type) and
316
- hasattr(item, 'name') and
317
- hasattr(item, 'description') and
318
- hasattr(item, 'parameters') and
319
- hasattr(item, 'execute') and
320
- item.name == module_name):
387
+ if (
388
+ isinstance(item, type)
389
+ and hasattr(item, "name")
390
+ and hasattr(item, "description")
391
+ and hasattr(item, "parameters")
392
+ and hasattr(item, "execute")
393
+ and item.name == module_name
394
+ ):
321
395
 
322
396
  if hasattr(item, "check"):
323
397
  if not item.check():
@@ -331,7 +405,7 @@ class ToolRegistry(OutputHandler):
331
405
  name=tool_instance.name,
332
406
  description=tool_instance.description,
333
407
  parameters=tool_instance.parameters,
334
- func=tool_instance.execute
408
+ func=tool_instance.execute,
335
409
  )
336
410
  tool_found = True
337
411
  break
@@ -346,14 +420,19 @@ class ToolRegistry(OutputHandler):
346
420
  sys.path.remove(parent_dir)
347
421
 
348
422
  except Exception as e:
349
- PrettyOutput.print(f"从 {Path(file_path).name} 加载工具失败: {str(e)}", OutputType.ERROR)
423
+ PrettyOutput.print(
424
+ f"从 {Path(file_path).name} 加载工具失败: {str(e)}", OutputType.ERROR
425
+ )
350
426
  return False
351
-
427
+
352
428
  @staticmethod
353
429
  def _has_tool_calls_block(content: str) -> bool:
354
430
  """从内容中提取工具调用块"""
355
- return re.search(ot("TOOL_CALL")+r'(.*?)'+ct("TOOL_CALL"), content, re.DOTALL) is not None
356
-
431
+ return (
432
+ re.search(ot("TOOL_CALL") + r"(.*?)" + ct("TOOL_CALL"), content, re.DOTALL)
433
+ is not None
434
+ )
435
+
357
436
  @staticmethod
358
437
  def _extract_tool_calls(content: str) -> Tuple[Dict[str, Dict[str, Any]], str]:
359
438
  """从内容中提取工具调用。
@@ -368,28 +447,42 @@ class ToolRegistry(OutputHandler):
368
447
  Exception: 如果工具调用缺少必要字段
369
448
  """
370
449
  # 将内容拆分为行
371
- data = re.findall(ot("TOOL_CALL")+r'(.*?)'+ct("TOOL_CALL"), content, re.DOTALL)
450
+ data = re.findall(
451
+ ot("TOOL_CALL") + r"(.*?)" + ct("TOOL_CALL"), content, re.DOTALL
452
+ )
372
453
  ret = []
373
454
  for item in data:
374
455
  try:
375
456
  msg = yaml.safe_load(item)
376
- if 'name' in msg and 'arguments' in msg and 'want' in msg:
457
+ if "name" in msg and "arguments" in msg and "want" in msg:
377
458
  ret.append(msg)
378
459
  else:
379
- return {}, f"""工具调用格式错误,请检查工具调用格式。
380
-
381
- {tool_call_help}"""
460
+ return (
461
+ {},
462
+ f"""工具调用格式错误,请检查工具调用格式。
463
+
464
+ {tool_call_help}""",
465
+ )
382
466
  except Exception as e:
383
- return {}, f"""工具调用格式错误,请检查工具调用格式。
384
-
385
- {tool_call_help}"""
467
+ return (
468
+ {},
469
+ f"""工具调用格式错误,请检查工具调用格式。
470
+
471
+ {tool_call_help}""",
472
+ )
386
473
  if len(ret) > 1:
387
474
  return {}, "检测到多个工具调用,请一次只处理一个工具调用。"
388
475
  return ret[0] if ret else {}, ""
389
476
 
390
- def register_tool(self, name: str, description: str, parameters: Dict[str, Dict[str, Any]], func: Callable[..., Dict[str, Any]]) -> None:
477
+ def register_tool(
478
+ self,
479
+ name: str,
480
+ description: str,
481
+ parameters: Any,
482
+ func: Callable[..., Dict[str, Any]],
483
+ ) -> None:
391
484
  """注册新工具
392
-
485
+
393
486
  参数:
394
487
  name: 工具名称
395
488
  description: 工具描述
@@ -400,10 +493,10 @@ class ToolRegistry(OutputHandler):
400
493
 
401
494
  def get_tool(self, name: str) -> Optional[Tool]:
402
495
  """获取工具
403
-
496
+
404
497
  参数:
405
498
  name: 工具名称
406
-
499
+
407
500
  返回:
408
501
  Optional[Tool]: 找到的工具实例,如果不存在则返回None
409
502
  """
@@ -411,7 +504,7 @@ class ToolRegistry(OutputHandler):
411
504
 
412
505
  def get_all_tools(self) -> List[Dict[str, Any]]:
413
506
  """获取所有工具(Ollama格式定义)
414
-
507
+
415
508
  返回:
416
509
  List[Dict[str, Any]]: 包含所有工具信息的列表
417
510
  """
@@ -419,17 +512,21 @@ class ToolRegistry(OutputHandler):
419
512
 
420
513
  def execute_tool(self, name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
421
514
  """执行指定工具
422
-
515
+
423
516
  参数:
424
517
  name: 工具名称
425
518
  arguments: 工具参数
426
-
519
+
427
520
  返回:
428
521
  Dict[str, Any]: 包含执行结果的字典,包含success、stdout和stderr字段
429
522
  """
430
523
  tool = self.get_tool(name)
431
524
  if tool is None:
432
- return {"success": False, "stderr": f"工具 {name} 不存在,可用的工具有: {', '.join(self.tools.keys())}", "stdout": ""}
525
+ return {
526
+ "success": False,
527
+ "stderr": f"工具 {name} 不存在,可用的工具有: {', '.join(self.tools.keys())}",
528
+ "stdout": "",
529
+ }
433
530
  return tool.execute(arguments)
434
531
 
435
532
  def _format_tool_output(self, stdout: str, stderr: str) -> str:
@@ -450,7 +547,6 @@ class ToolRegistry(OutputHandler):
450
547
  output = "\n\n".join(output_parts)
451
548
  return "无输出和错误" if not output else output
452
549
 
453
-
454
550
  def handle_tool_calls(self, tool_call: Dict[str, Any], agent: Any) -> str:
455
551
  try:
456
552
  name = tool_call["name"] # 确保name是str类型
@@ -462,30 +558,36 @@ class ToolRegistry(OutputHandler):
462
558
  try:
463
559
  args = json.loads(args)
464
560
  except json.JSONDecodeError:
465
- PrettyOutput.print(f"工具参数格式无效: {name} {tool_call_help}", OutputType.ERROR)
561
+ PrettyOutput.print(
562
+ f"工具参数格式无效: {name} {tool_call_help}", OutputType.ERROR
563
+ )
466
564
  return ""
467
565
 
468
566
  # 执行工具调用
469
567
  result = self.execute_tool(name, args) # 修正参数传递
470
568
 
471
569
  # 格式化输出
472
- output = self._format_tool_output(result["stdout"], result.get("stderr", ""))
570
+ output = self._format_tool_output(
571
+ result["stdout"], result.get("stderr", "")
572
+ )
473
573
 
474
574
  # 处理结果
475
575
  if get_context_token_count(output) > self.max_input_token_count:
476
- with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as tmp_file:
576
+ with tempfile.NamedTemporaryFile(
577
+ mode="w", suffix=".txt", delete=False
578
+ ) as tmp_file:
477
579
  output_file = tmp_file.name
478
580
  tmp_file.write(output)
479
581
  tmp_file.flush()
480
582
  platform: Any = PlatformRegistry().get_normal_platform()
481
583
  if platform:
482
584
  platform.set_suppress_output(False)
483
- platform.upload_files([output_file]) # TODO 处理错误
585
+ platform.upload_files([output_file]) # TODO 处理错误
484
586
  prompt = f"该文件为工具执行结果,请阅读文件内容,并根据文件提取出以下信息:{want}"
485
587
  return f"""工具调用原始输出过长,以下是根据输出提出的信息:
486
588
 
487
589
  {platform.chat_until_success(prompt)}"""
488
-
590
+
489
591
  return output
490
592
 
491
593
  except Exception as e:
@@ -500,33 +602,37 @@ def main() -> int:
500
602
 
501
603
  init_env()
502
604
 
503
- parser = argparse.ArgumentParser(description='Jarvis 工具系统命令行界面')
504
- subparsers = parser.add_subparsers(dest='command', help='命令')
605
+ parser = argparse.ArgumentParser(description="Jarvis 工具系统命令行界面")
606
+ subparsers = parser.add_subparsers(dest="command", help="命令")
505
607
 
506
608
  # 列出工具子命令
507
- list_parser = subparsers.add_parser('list', help='列出所有可用工具')
508
- list_parser.add_argument('--json', action='store_true', help='以JSON格式输出')
509
- list_parser.add_argument('--detailed', action='store_true', help='显示详细信息')
609
+ list_parser = subparsers.add_parser("list", help="列出所有可用工具")
610
+ list_parser.add_argument("--json", action="store_true", help="以JSON格式输出")
611
+ list_parser.add_argument("--detailed", action="store_true", help="显示详细信息")
510
612
 
511
613
  # 调用工具子命令
512
- call_parser = subparsers.add_parser('call', help='调用指定工具')
513
- call_parser.add_argument('tool_name', help='要调用的工具名称')
514
- call_parser.add_argument('--args', type=str, help='工具参数 (JSON格式)')
515
- call_parser.add_argument('--args-file', type=str, help='从文件加载工具参数 (JSON格式)')
614
+ call_parser = subparsers.add_parser("call", help="调用指定工具")
615
+ call_parser.add_argument("tool_name", help="要调用的工具名称")
616
+ call_parser.add_argument("--args", type=str, help="工具参数 (JSON格式)")
617
+ call_parser.add_argument(
618
+ "--args-file", type=str, help="从文件加载工具参数 (JSON格式)"
619
+ )
516
620
 
517
621
  args = parser.parse_args()
518
622
 
519
623
  # 初始化工具注册表
520
624
  registry = ToolRegistry()
521
625
 
522
- if args.command == 'list':
626
+ if args.command == "list":
523
627
  tools = registry.get_all_tools()
524
628
 
525
629
  if args.json:
526
630
  if args.detailed:
527
631
  print(json.dumps(tools, indent=2, ensure_ascii=False))
528
632
  else:
529
- simple_tools = [{"name": t["name"], "description": t["description"]} for t in tools]
633
+ simple_tools = [
634
+ {"name": t["name"], "description": t["description"]} for t in tools
635
+ ]
530
636
  print(json.dumps(simple_tools, indent=2, ensure_ascii=False))
531
637
  else:
532
638
  PrettyOutput.section("可用工具列表", OutputType.SYSTEM)
@@ -535,14 +641,9 @@ def main() -> int:
535
641
  print(f" 描述: {tool['description']}")
536
642
  if args.detailed:
537
643
  print(f" 参数:")
538
- params = tool['parameters'].get('properties', {})
539
- required = tool['parameters'].get('required', [])
540
- for param_name, param_info in params.items():
541
- req_mark = "*" if param_name in required else ""
542
- desc = param_info.get('description', '无描述')
543
- print(f" - {param_name}{req_mark}: {desc}")
544
-
545
- elif args.command == 'call':
644
+ print(tool["parameters"])
645
+
646
+ elif args.command == "call":
546
647
  tool_name = args.tool_name
547
648
  tool_obj = registry.get_tool(tool_name)
548
649
 
@@ -563,23 +664,27 @@ def main() -> int:
563
664
 
564
665
  elif args.args_file:
565
666
  try:
566
- with open(args.args_file, 'r', encoding='utf-8') as f:
667
+ with open(args.args_file, "r", encoding="utf-8") as f:
567
668
  tool_args = json.load(f)
568
669
  except (json.JSONDecodeError, FileNotFoundError) as e:
569
- PrettyOutput.print(f"错误: 无法从文件加载参数: {str(e)}", OutputType.ERROR)
670
+ PrettyOutput.print(
671
+ f"错误: 无法从文件加载参数: {str(e)}", OutputType.ERROR
672
+ )
570
673
  return 1
571
674
 
572
675
  # 检查必需参数
573
- required_params = tool_obj.parameters.get('required', [])
676
+ required_params = tool_obj.parameters.get("required", [])
574
677
  missing_params = [p for p in required_params if p not in tool_args]
575
678
 
576
679
  if missing_params:
577
- PrettyOutput.print(f"错误: 缺少必需参数: {', '.join(missing_params)}", OutputType.ERROR)
680
+ PrettyOutput.print(
681
+ f"错误: 缺少必需参数: {', '.join(missing_params)}", OutputType.ERROR
682
+ )
578
683
  print("\n参数说明:")
579
- params = tool_obj.parameters.get('properties', {})
684
+ params = tool_obj.parameters.get("properties", {})
580
685
  for param_name in required_params:
581
686
  param_info = params.get(param_name, {})
582
- desc = param_info.get('description', '无描述')
687
+ desc = param_info.get("description", "无描述")
583
688
  print(f" - {param_name}: {desc}")
584
689
  return 1
585
690
 
@@ -29,7 +29,7 @@ def get_max_input_token_count() -> int:
29
29
  返回:
30
30
  int: 模型能处理的最大输入token数量。
31
31
  """
32
- return int(os.getenv('JARVIS_MAX_INPUT_TOKEN_COUNT', '32000'))
32
+ return int(os.getenv('JARVIS_MAX_INPUT_TOKEN_COUNT', '64000'))
33
33
 
34
34
 
35
35
  def is_auto_complete() -> bool:
@@ -141,13 +141,13 @@ def load_methodology(user_input: str) -> str:
141
141
 
142
142
  platform.set_suppress_output(False)
143
143
  # 构建提示信息
144
- prompt = f"""根据用户需求: {user_input}
144
+ prompt = f"""根据用户需求和已有的方法论内容,总结出与该任务/需求相关的方法论: {user_input}
145
145
 
146
146
  请按以下格式回复:
147
- ### 相关的方法论
147
+ ### 与该任务/需求相关的方法论
148
148
  1. [方法论名字]
149
149
  2. [方法论名字]
150
- ### 总结的方法论内容
150
+ ### 根据以上方法论,总结出方法论内容
151
151
  [总结的方法论内容]
152
152
 
153
153
  如果没有匹配的方法论,请输出:没有历史方法论可参考