jarvis-ai-assistant 0.1.223__py3-none-any.whl → 0.1.224__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 CHANGED
@@ -1,4 +1,4 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  """Jarvis AI Assistant"""
3
3
 
4
- __version__ = "0.1.223"
4
+ __version__ = "0.1.224"
@@ -92,6 +92,10 @@ class Agent:
92
92
  # 只有在记录启动时才停止记录
93
93
  delete_agent(self.name)
94
94
 
95
+ def get_tool_usage_prompt(self) -> str:
96
+ """获取工具使用提示"""
97
+ return build_action_prompt(self.output_handler) # type: ignore
98
+
95
99
  def __init__(
96
100
  self,
97
101
  system_prompt: str,
@@ -199,7 +203,7 @@ class Agent:
199
203
 
200
204
  PrettyOutput.print(welcome_message, OutputType.SYSTEM)
201
205
 
202
- action_prompt = build_action_prompt(self.output_handler) # type: ignore
206
+ action_prompt = self.get_tool_usage_prompt()
203
207
 
204
208
  self.model.set_system_prompt(
205
209
  f"""
@@ -38,10 +38,7 @@ def builtin_input_handler(user_input: str, agent_: Any) -> Tuple[str, bool]:
38
38
  agent.clear()
39
39
  return "", True
40
40
  elif tag == "ToolUsage":
41
- from jarvis.jarvis_tools.registry import ToolRegistry
42
- from jarvis.jarvis_agent.prompt_builder import build_action_prompt
43
- action_prompt = build_action_prompt(agent.output_handler) # type: ignore
44
- agent.set_addon_prompt(action_prompt)
41
+ agent.set_addon_prompt(agent.get_tool_usage_prompt())
45
42
  return "", False
46
43
  elif tag == "ReloadConfig":
47
44
  from jarvis.jarvis_utils.utils import load_config
@@ -176,6 +176,14 @@
176
176
  "description": "是否启用任务分析",
177
177
  "default": true
178
178
  },
179
+ "JARVIS_TOOL_LOAD_DIRS": {
180
+ "type": "array",
181
+ "description": "自定义工具加载目录",
182
+ "items": {
183
+ "type": "string"
184
+ },
185
+ "default": []
186
+ },
179
187
  "JARVIS_PRINT_PROMPT": {
180
188
  "type": "boolean",
181
189
  "description": "是否打印提示",
@@ -229,7 +237,35 @@
229
237
  "template"
230
238
  ]
231
239
  }
240
+ },
241
+ "OPENAI_API_KEY": {
242
+ "type": "string",
243
+ "description": "OpenAI API Key"
244
+ },
245
+ "OPENAI_API_BASE": {
246
+ "type": "string",
247
+ "description": "OpenAI API Base URL"
248
+ },
249
+ "KIMI_API_KEY": {
250
+ "type": "string",
251
+ "description": "Kimi API Key"
252
+ },
253
+ "TONGYI_COOKIES": {
254
+ "type": "string",
255
+ "description": "Tongyi Cookies"
256
+ },
257
+ "YUANBAO_COOKIES": {
258
+ "type": "string",
259
+ "description": "Yuanbao Cookies"
260
+ },
261
+ "AI8_API_KEY": {
262
+ "type": "string",
263
+ "description": "AI8 API Key"
264
+ },
265
+ "OYI_API_KEY": {
266
+ "type": "string",
267
+ "description": "Oyi API Key"
232
268
  }
233
269
  },
234
- "additionalProperties": false
270
+ "additionalProperties": true
235
271
  }
jarvis/jarvis_rag/cli.py CHANGED
@@ -4,7 +4,7 @@ from pathlib import Path
4
4
  from typing import Optional, List, Literal, cast
5
5
  import mimetypes
6
6
 
7
- import pathspec
7
+ import pathspec # type: ignore
8
8
  import typer
9
9
  from langchain.docstore.document import Document
10
10
  from langchain_community.document_loaders import (
@@ -14,7 +14,7 @@ from jarvis.jarvis_mcp.sse_mcp_client import SSEMcpClient
14
14
  from jarvis.jarvis_mcp.stdio_mcp_client import StdioMcpClient
15
15
  from jarvis.jarvis_mcp.streamable_mcp_client import StreamableMcpClient
16
16
  from jarvis.jarvis_tools.base import Tool
17
- from jarvis.jarvis_utils.config import get_data_dir
17
+ from jarvis.jarvis_utils.config import get_data_dir, get_tool_load_dirs
18
18
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
19
19
  from jarvis.jarvis_utils.tag import ct, ot
20
20
  from jarvis.jarvis_utils.utils import is_context_overflow
@@ -118,7 +118,7 @@ class ToolRegistry(OutputHandlerProtocol):
118
118
  return "TOOL_CALL"
119
119
 
120
120
  def can_handle(self, response: str) -> bool:
121
- return ToolRegistry._has_tool_calls_block(response)
121
+ return ot("TOOL_CALL") in response
122
122
 
123
123
  def prompt(self) -> str:
124
124
  """加载工具"""
@@ -165,11 +165,21 @@ class ToolRegistry(OutputHandlerProtocol):
165
165
  return tools_prompt
166
166
  return ""
167
167
 
168
- def handle(self, response: str, agent: Any) -> Tuple[bool, Any]:
169
- tool_call, err_msg = self._extract_tool_calls(response)
170
- if err_msg:
171
- return False, err_msg
172
- return False, self.handle_tool_calls(tool_call, agent)
168
+ def handle(self, response: str, agent_: Any) -> Tuple[bool, Any]:
169
+ try:
170
+ tool_call, err_msg = self._extract_tool_calls(response)
171
+ if err_msg:
172
+ return False, err_msg
173
+ return False, self.handle_tool_calls(tool_call, agent_)
174
+ except Exception as e:
175
+ PrettyOutput.print(f"工具调用处理失败: {str(e)}", OutputType.ERROR)
176
+ from jarvis.jarvis_agent import Agent
177
+
178
+ agent: Agent = agent_
179
+ return (
180
+ False,
181
+ f"工具调用处理失败: {str(e)}\n\n{agent.get_tool_usage_prompt()}",
182
+ )
173
183
 
174
184
  def __init__(self) -> None:
175
185
  """初始化工具注册表"""
@@ -276,18 +286,22 @@ class ToolRegistry(OutputHandlerProtocol):
276
286
  self.register_tool_by_file(str(file_path))
277
287
 
278
288
  def _load_external_tools(self) -> None:
279
- """从jarvis_data/tools加载外部工具"""
280
- external_tools_dir = Path(get_data_dir()) / "tools"
281
- if not external_tools_dir.exists():
282
- return
289
+ """从jarvis_data/tools和配置的目录加载外部工具"""
290
+ tool_dirs = [Path(get_data_dir()) / "tools"] + [
291
+ Path(p) for p in get_tool_load_dirs()
292
+ ]
283
293
 
284
- # 遍历目录中的所有.py文件
285
- for file_path in external_tools_dir.glob("*.py"):
286
- # 跳过__init__.py
287
- if file_path.name == "__init__.py":
294
+ for tool_dir in tool_dirs:
295
+ if not tool_dir.exists():
288
296
  continue
289
297
 
290
- self.register_tool_by_file(str(file_path))
298
+ # 遍历目录中的所有.py文件
299
+ for file_path in tool_dir.glob("*.py"):
300
+ # 跳过__init__.py
301
+ if file_path.name == "__init__.py":
302
+ continue
303
+
304
+ self.register_tool_by_file(str(file_path))
291
305
 
292
306
  def register_mcp_tool_by_config(self, config: Dict[str, Any]) -> bool:
293
307
  """从配置字典加载并注册工具
@@ -396,12 +410,13 @@ class ToolRegistry(OutputHandlerProtocol):
396
410
  return False
397
411
 
398
412
  # 创建MCP客户端
413
+ mcp_client: McpClient
399
414
  if config["type"] == "stdio":
400
- mcp_client: McpClient = StdioMcpClient(config)
415
+ mcp_client = StdioMcpClient(config)
401
416
  elif config["type"] == "sse":
402
- mcp_client: McpClient = SSEMcpClient(config)
417
+ mcp_client = SSEMcpClient(config)
403
418
  elif config["type"] == "streamable":
404
- mcp_client: McpClient = StreamableMcpClient(config)
419
+ mcp_client = StreamableMcpClient(config)
405
420
  else:
406
421
  raise ValueError(f"不支持的MCP客户端类型: {config['type']}")
407
422
 
@@ -549,6 +564,8 @@ class ToolRegistry(OutputHandlerProtocol):
549
564
  data = re.findall(
550
565
  ot("TOOL_CALL") + r"(.*?)" + ct("TOOL_CALL"), content, re.DOTALL
551
566
  )
567
+ if not data:
568
+ return {}, f"只有{ot('TOOL_CALL')}标签,未找到{ct('TOOL_CALL')}标签,调用格式错误,请检查工具调用格式。\n{tool_call_help}"
552
569
  ret = []
553
570
  for item in data:
554
571
  try:
@@ -3,7 +3,6 @@ import os
3
3
  from functools import lru_cache
4
4
  from typing import Any, Dict, List
5
5
 
6
- import torch
7
6
  import yaml # type: ignore
8
7
 
9
8
  from jarvis.jarvis_utils.builtin_replace_map import BUILTIN_REPLACE_MAP
@@ -231,6 +230,16 @@ def is_use_analysis() -> bool:
231
230
  return GLOBAL_CONFIG_DATA.get("JARVIS_USE_ANALYSIS", True) == True
232
231
 
233
232
 
233
+ def get_tool_load_dirs() -> List[str]:
234
+ """
235
+ 获取工具加载目录。
236
+
237
+ 返回:
238
+ List[str]: 工具加载目录列表
239
+ """
240
+ return GLOBAL_CONFIG_DATA.get("JARVIS_TOOL_LOAD_DIRS", [])
241
+
242
+
234
243
  def is_print_prompt() -> bool:
235
244
  """
236
245
  获取是否打印提示。
@@ -16,7 +16,7 @@ import subprocess
16
16
  import sys
17
17
  from typing import Any, Dict, List, Set, Tuple
18
18
 
19
- from jarvis.jarvis_utils.config import is_confirm_before_apply_patch
19
+ from jarvis.jarvis_utils.config import get_data_dir, is_confirm_before_apply_patch
20
20
  from jarvis.jarvis_utils.output import OutputType, PrettyOutput
21
21
  from jarvis.jarvis_utils.input import user_confirm
22
22
 
@@ -339,25 +339,21 @@ def check_and_update_git_repo(repo_path: str) -> bool:
339
339
  返回:
340
340
  bool: 是否执行了更新
341
341
  """
342
+ # 检查上次检查日期
343
+ last_check_file = os.path.join(get_data_dir(), "last_git_check")
344
+ today_str = datetime.date.today().strftime("%Y-%m-%d")
345
+ if os.path.exists(last_check_file):
346
+ with open(last_check_file, "r") as f:
347
+ last_check_date = f.read().strip()
348
+ if last_check_date == today_str:
349
+ return False
350
+
342
351
  curr_dir = os.path.abspath(os.getcwd())
343
352
  git_root = find_git_root_and_cd(repo_path)
344
353
  if git_root is None:
345
354
  return False
346
355
 
347
356
  try:
348
- # 检查最新提交时间是否为今天
349
- commit_date_result = subprocess.run(
350
- ["git", "log", "-1", "--format=%cd", "--date=short"],
351
- cwd=git_root,
352
- capture_output=True,
353
- text=True,
354
- )
355
- if commit_date_result.returncode == 0:
356
- commit_date = commit_date_result.stdout.strip()
357
- today = datetime.date.today().strftime("%Y-%m-%d")
358
- if commit_date == today:
359
- return False
360
-
361
357
  # 检查是否有未提交的修改
362
358
  if has_uncommitted_changes():
363
359
  return False
@@ -454,6 +450,9 @@ def check_and_update_git_repo(repo_path: str) -> bool:
454
450
  f"安装过程中发生意外错误: {str(e)}", OutputType.ERROR
455
451
  )
456
452
  return False
453
+ # 更新检查日期文件
454
+ with open(last_check_file, "w") as f:
455
+ f.write(today_str)
457
456
  return False
458
457
  except Exception as e:
459
458
  PrettyOutput.print(f"Git仓库更新检查失败: {e}", OutputType.WARNING)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jarvis-ai-assistant
3
- Version: 0.1.223
3
+ Version: 0.1.224
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
@@ -1,6 +1,6 @@
1
- jarvis/__init__.py,sha256=YlYf-txS383hefwOHMnCEByeqa-lDVLEbMwcCc7hY3Q,75
2
- jarvis/jarvis_agent/__init__.py,sha256=l37t2lnXsPeQEwPkqrQWmqQ0ogh37GY-iAOQxkjttzY,21479
3
- jarvis/jarvis_agent/builtin_input_handler.py,sha256=MtPm7N78hPJJJ9PV_p8pkyDE7epBmtngrE9Xn-wbnH8,2682
1
+ jarvis/__init__.py,sha256=gaZuEX29UqdWvgGIXuboMfdenif5NCuNvfhYM6Ffzqg,75
2
+ jarvis/jarvis_agent/__init__.py,sha256=PHTP4P0iOCzdozNYj2d02a-yz-4pm8TykaUqzji7H4I,21607
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
5
  jarvis/jarvis_agent/jarvis.py,sha256=2Ilt-eLs-dCvD6V1-UGyJ3PleY0AozkYhi8Rx6_zUr4,6315
6
6
  jarvis/jarvis_agent/main.py,sha256=nXOw2mewhYYmj_8rohcEmETjUFqror1NiRwDusFMUKQ,3055
@@ -35,7 +35,7 @@ jarvis/jarvis_code_analysis/checklists/shell.py,sha256=aRFYhQQvTgbYd-uY5pc8UHIUA
35
35
  jarvis/jarvis_code_analysis/checklists/sql.py,sha256=vR0T6qC7b4dURjJVAd7kSVxyvZEQXPG1Jqc2sNTGp5c,2355
36
36
  jarvis/jarvis_code_analysis/checklists/swift.py,sha256=TPx4I6Gupvs6tSerRKmTSKEPQpOLEbH2Y7LXg1uBgxc,2566
37
37
  jarvis/jarvis_code_analysis/checklists/web.py,sha256=25gGD7pDadZQybNFvALYxWvK0VRjGQb1NVJQElwjyk0,3943
38
- jarvis/jarvis_data/config_schema.json,sha256=t51JvUc2IEe-QWP5bbocB7sqQAkmtUrPEHSHPfqzDjU,6668
38
+ jarvis/jarvis_data/config_schema.json,sha256=uuDN-25NJRnKfb6KuuqxOnfRGMphkKQbjxfu0Me6pAI,7494
39
39
  jarvis/jarvis_data/tiktoken/9b5ad71b2ce5302211f9c61530b329a4922fc6a4,sha256=Ijkht27pm96ZW3_3OFE-7xAPtR0YyTWXoRO8_-hlsqc,1681126
40
40
  jarvis/jarvis_git_details/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
41
  jarvis/jarvis_git_details/main.py,sha256=DE1DcX-1lvUsb_K-FExpHs3NBRmo5KZb53PGa8QFBOc,8875
@@ -64,7 +64,7 @@ jarvis/jarvis_platform_manager/main.py,sha256=LxlXSfIfmkYNcajOG_XvvlmwlSWSGb0Dmb
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
- jarvis/jarvis_rag/cli.py,sha256=iR26y7ZLj4HECl3zveY4fxwn-mhMnQ__IxHQo2NAwD0,13143
67
+ jarvis/jarvis_rag/cli.py,sha256=q1W7XWZ7u7oMckqeNUX7YQoiQ3PzT3Rh-FZvTeG_U3I,13159
68
68
  jarvis/jarvis_rag/embedding_manager.py,sha256=BoV6Vr_3F4zbjBAOQ1FdEBnJXGPwBkv1IEkdRP9CgFw,3338
69
69
  jarvis/jarvis_rag/llm_interface.py,sha256=44Uu04v2_MxweLmMdR0YWbnxlfchAPAzLBEQmJdLjeU,4368
70
70
  jarvis/jarvis_rag/query_rewriter.py,sha256=JM1Q23zZISze77BleRgTPgNAtLUtLAXkEo3G70kaTK8,2190
@@ -83,7 +83,7 @@ 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=0SdgBi-b1qnd3QX0VvQy7UVU7Pq9BZGYLiAe7t0DjpQ,25690
86
+ jarvis/jarvis_tools/registry.py,sha256=KA6dw5ka_OSg0BNuVdk0tN8X0InaOWxKgkEs2XOiHFQ,26386
87
87
  jarvis/jarvis_tools/rewrite_file.py,sha256=eG_WKg6cVAXmuGwUqlWkcuyay5S8DOzEi8vZCmX3O8w,7255
88
88
  jarvis/jarvis_tools/search_web.py,sha256=DqBwNGFK3vZleZ7_4Go3q27DzPCp4m0ZeEi1N7UEFc4,5363
89
89
  jarvis/jarvis_tools/virtual_tty.py,sha256=KKr3jpvQWWMPr2o40hlmN6fuXJCN8H4_ma5QU40Citc,16089
@@ -91,10 +91,10 @@ jarvis/jarvis_tools/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
91
91
  jarvis/jarvis_tools/cli/main.py,sha256=Mg6TQDxMdzB1Ua1UrZ2EE-uQWsbaeojWaEGHJp2HimA,6375
92
92
  jarvis/jarvis_utils/__init__.py,sha256=67h0ldisGlh3oK4DAeNEL2Bl_VsI3tSmfclasyVlueM,850
93
93
  jarvis/jarvis_utils/builtin_replace_map.py,sha256=EI8JnHqr-ZpAhpwocTu48DhHUMHNd8tNUpDNYI47OLE,1717
94
- jarvis/jarvis_utils/config.py,sha256=E8GhbpbdGyrAxTC89wN7KGE2rJ9zwhmL-HMIgTl9q18,8051
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
97
- jarvis/jarvis_utils/git_utils.py,sha256=4mNbEgV0icMnB1UL1RWhE9Nxik3mwam2qcGMpd1ODJM,21707
97
+ jarvis/jarvis_utils/git_utils.py,sha256=EpyS8AvvK9M9WnkObtQsU2gXq45PnY-WJo2c4kMtyFM,21702
98
98
  jarvis/jarvis_utils/globals.py,sha256=WzZh_acNfHJj1LDulhyLQ7cojksBy0gdrITe0vH1XA0,3901
99
99
  jarvis/jarvis_utils/http.py,sha256=Uqt1kcz0HWnAfXHHi1fNGwLb2lcVUqpbrG2Uk_-kcIU,4882
100
100
  jarvis/jarvis_utils/input.py,sha256=V2w3xV0MO73c4Y4XY_yy9jVNg7MmN76FmAnpKRiJUog,9160
@@ -102,9 +102,9 @@ jarvis/jarvis_utils/methodology.py,sha256=-cvM6pwgJK7BXCYg2uVjIId_j3v5RUh2z2PBcK
102
102
  jarvis/jarvis_utils/output.py,sha256=PRCgudPOB8gMEP3u-g0FGD2c6tBgJhLXUMqNPglfjV8,10813
103
103
  jarvis/jarvis_utils/tag.py,sha256=f211opbbbTcSyzCDwuIK_oCnKhXPNK-RknYyGzY1yD0,431
104
104
  jarvis/jarvis_utils/utils.py,sha256=ojupkZQfFIE6ysTyCy0jUdePucpwpvZlZJSXkGsdyQE,15263
105
- jarvis_ai_assistant-0.1.223.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
106
- jarvis_ai_assistant-0.1.223.dist-info/METADATA,sha256=Fn58Cq6CpCpo9MjyYGrSWjI9Y2M90LA6VW9IjOu2tOE,24061
107
- jarvis_ai_assistant-0.1.223.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
108
- jarvis_ai_assistant-0.1.223.dist-info/entry_points.txt,sha256=JXK_n-d9HZ_RLz959CvpK5-UPOCwssn5oAH8dAHuebA,1277
109
- jarvis_ai_assistant-0.1.223.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
110
- jarvis_ai_assistant-0.1.223.dist-info/RECORD,,
105
+ jarvis_ai_assistant-0.1.224.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
106
+ jarvis_ai_assistant-0.1.224.dist-info/METADATA,sha256=UAICgGTzfZc6Gob8uMokO0qUUENIvYUKZQidjdCyq5w,24061
107
+ jarvis_ai_assistant-0.1.224.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
108
+ jarvis_ai_assistant-0.1.224.dist-info/entry_points.txt,sha256=JXK_n-d9HZ_RLz959CvpK5-UPOCwssn5oAH8dAHuebA,1277
109
+ jarvis_ai_assistant-0.1.224.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
110
+ jarvis_ai_assistant-0.1.224.dist-info/RECORD,,