jarvis-ai-assistant 0.1.5__py3-none-any.whl → 0.1.7__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.
- jarvis/__init__.py +1 -1
- jarvis/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/__pycache__/agent.cpython-313.pyc +0 -0
- jarvis/__pycache__/main.cpython-313.pyc +0 -0
- jarvis/__pycache__/models.cpython-313.pyc +0 -0
- jarvis/__pycache__/utils.cpython-313.pyc +0 -0
- jarvis/__pycache__/zte_llm.cpython-313.pyc +0 -0
- jarvis/agent.py +235 -70
- jarvis/main.py +30 -14
- jarvis/models.py +72 -60
- jarvis/tools/__init__.py +1 -3
- jarvis/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/base.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/file_ops.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/search.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/shell.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/sub_agent.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/user_input.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/webpage.cpython-313.pyc +0 -0
- jarvis/tools/base.py +49 -128
- jarvis/tools/file_ops.py +1 -1
- jarvis/tools/search.py +77 -14
- jarvis/tools/shell.py +44 -49
- jarvis/tools/sub_agent.py +29 -25
- jarvis/tools/webpage.py +12 -26
- jarvis/utils.py +101 -65
- jarvis/zte_llm.py +28 -25
- {jarvis_ai_assistant-0.1.5.dist-info → jarvis_ai_assistant-0.1.7.dist-info}/METADATA +2 -1
- jarvis_ai_assistant-0.1.7.dist-info/RECORD +37 -0
- jarvis/.jarvis +0 -1
- jarvis/tools/python_script.py +0 -150
- jarvis_ai_assistant-0.1.5.dist-info/RECORD +0 -38
- {jarvis_ai_assistant-0.1.5.dist-info → jarvis_ai_assistant-0.1.7.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.5.dist-info → jarvis_ai_assistant-0.1.7.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.5.dist-info → jarvis_ai_assistant-0.1.7.dist-info}/top_level.txt +0 -0
jarvis/tools/webpage.py
CHANGED
|
@@ -5,19 +5,13 @@ from ..utils import PrettyOutput, OutputType
|
|
|
5
5
|
|
|
6
6
|
class WebpageTool:
|
|
7
7
|
name = "read_webpage"
|
|
8
|
-
description = "
|
|
8
|
+
description = "读取网页内容,提取标题和正文文本"
|
|
9
9
|
parameters = {
|
|
10
10
|
"type": "object",
|
|
11
11
|
"properties": {
|
|
12
12
|
"url": {
|
|
13
13
|
"type": "string",
|
|
14
|
-
"description": "URL
|
|
15
|
-
},
|
|
16
|
-
"extract_type": {
|
|
17
|
-
"type": "string",
|
|
18
|
-
"description": "Type of content to extract: 'text', 'title', or 'all'",
|
|
19
|
-
"enum": ["text", "title", "all"],
|
|
20
|
-
"default": "all"
|
|
14
|
+
"description": "需要读取的网页URL"
|
|
21
15
|
}
|
|
22
16
|
},
|
|
23
17
|
"required": ["url"]
|
|
@@ -27,7 +21,6 @@ class WebpageTool:
|
|
|
27
21
|
"""读取网页内容"""
|
|
28
22
|
try:
|
|
29
23
|
url = args["url"]
|
|
30
|
-
extract_type = args.get("extract_type", "all")
|
|
31
24
|
|
|
32
25
|
# 设置请求头
|
|
33
26
|
headers = {
|
|
@@ -49,28 +42,21 @@ class WebpageTool:
|
|
|
49
42
|
for script in soup(["script", "style"]):
|
|
50
43
|
script.decompose()
|
|
51
44
|
|
|
52
|
-
result = {}
|
|
53
|
-
|
|
54
45
|
# 提取标题
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
result["title"] = title.strip() if title else "无标题"
|
|
46
|
+
title = soup.title.string if soup.title else ""
|
|
47
|
+
title = title.strip() if title else "无标题"
|
|
58
48
|
|
|
59
49
|
# 提取正文
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
lines = [line.strip() for line in text.splitlines() if line.strip()]
|
|
63
|
-
result["text"] = "\n".join(lines)
|
|
50
|
+
text = soup.get_text(separator='\n', strip=True)
|
|
51
|
+
lines = [line.strip() for line in text.splitlines() if line.strip()]
|
|
64
52
|
|
|
65
53
|
# 构建输出
|
|
66
|
-
output = [
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
output.append("正文内容:")
|
|
73
|
-
output.append(result["text"])
|
|
54
|
+
output = [
|
|
55
|
+
f"标题: {title}",
|
|
56
|
+
"",
|
|
57
|
+
"正文内容:",
|
|
58
|
+
"\n".join(lines)
|
|
59
|
+
]
|
|
74
60
|
|
|
75
61
|
return {
|
|
76
62
|
"success": True,
|
jarvis/utils.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
import sys
|
|
3
3
|
import time
|
|
4
|
-
import threading
|
|
5
4
|
from typing import Dict, Optional
|
|
6
5
|
from enum import Enum
|
|
7
6
|
from datetime import datetime
|
|
@@ -12,77 +11,112 @@ import os
|
|
|
12
11
|
# 初始化colorama
|
|
13
12
|
colorama.init()
|
|
14
13
|
|
|
15
|
-
class Spinner:
|
|
16
|
-
"""加载动画类"""
|
|
17
|
-
def __init__(self, message: str = "思考中"):
|
|
18
|
-
self.spinner_chars = "⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏"
|
|
19
|
-
self.message = message
|
|
20
|
-
self.running = False
|
|
21
|
-
self.spinner_thread = None
|
|
22
|
-
|
|
23
|
-
def _spin(self):
|
|
24
|
-
i = 0
|
|
25
|
-
while self.running:
|
|
26
|
-
sys.stdout.write(f"\r{Fore.BLUE}{self.spinner_chars[i]} {self.message}...{Style.RESET_ALL}")
|
|
27
|
-
sys.stdout.flush()
|
|
28
|
-
time.sleep(0.1)
|
|
29
|
-
i = (i + 1) % len(self.spinner_chars)
|
|
30
|
-
sys.stdout.write("\r" + " " * (len(self.message) + 10) + "\r")
|
|
31
|
-
sys.stdout.flush()
|
|
32
|
-
|
|
33
|
-
def start(self):
|
|
34
|
-
self.running = True
|
|
35
|
-
self.spinner_thread = threading.Thread(target=self._spin)
|
|
36
|
-
self.spinner_thread.start()
|
|
37
|
-
|
|
38
|
-
def stop(self):
|
|
39
|
-
self.running = False
|
|
40
|
-
if self.spinner_thread:
|
|
41
|
-
self.spinner_thread.join()
|
|
42
|
-
|
|
43
14
|
class OutputType(Enum):
|
|
44
|
-
SYSTEM = "system"
|
|
45
|
-
CODE = "code"
|
|
46
|
-
RESULT = "result"
|
|
47
|
-
ERROR = "error"
|
|
48
|
-
INFO = "info"
|
|
15
|
+
SYSTEM = "system" # AI助手消息
|
|
16
|
+
CODE = "code" # 代码相关
|
|
17
|
+
RESULT = "result" # 工具执行结果
|
|
18
|
+
ERROR = "error" # 错误信息
|
|
19
|
+
INFO = "info" # 系统提示
|
|
20
|
+
PLANNING = "planning" # 任务规划
|
|
21
|
+
PROGRESS = "progress" # 执行进度
|
|
22
|
+
SUCCESS = "success" # 成功信息
|
|
23
|
+
WARNING = "warning" # 警告信息
|
|
24
|
+
DEBUG = "debug" # 调试信息
|
|
25
|
+
USER = "user" # 用户输入
|
|
26
|
+
TOOL = "tool" # 工具调用
|
|
49
27
|
|
|
50
28
|
class PrettyOutput:
|
|
51
29
|
"""美化输出类"""
|
|
30
|
+
|
|
31
|
+
# 颜色方案 - 只使用前景色
|
|
32
|
+
COLORS = {
|
|
33
|
+
OutputType.SYSTEM: Fore.CYAN, # 青色 - AI助手
|
|
34
|
+
OutputType.CODE: Fore.GREEN, # 绿色 - 代码
|
|
35
|
+
OutputType.RESULT: Fore.BLUE, # 蓝色 - 结果
|
|
36
|
+
OutputType.ERROR: Fore.RED, # 红色 - 错误
|
|
37
|
+
OutputType.INFO: Fore.YELLOW, # 黄色 - 提示
|
|
38
|
+
OutputType.PLANNING: Fore.MAGENTA, # 紫色 - 规划
|
|
39
|
+
OutputType.PROGRESS: Fore.WHITE, # 白色 - 进度
|
|
40
|
+
OutputType.SUCCESS: Fore.GREEN, # 绿色 - 成功
|
|
41
|
+
OutputType.WARNING: Fore.YELLOW, # 黄色 - 警告
|
|
42
|
+
OutputType.DEBUG: Fore.BLUE, # 蓝色 - 调试
|
|
43
|
+
OutputType.USER: Fore.GREEN, # 绿色 - 用户
|
|
44
|
+
OutputType.TOOL: Fore.YELLOW, # 黄色 - 工具
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
# 图标方案
|
|
48
|
+
ICONS = {
|
|
49
|
+
OutputType.SYSTEM: "🤖", # 机器人 - AI助手
|
|
50
|
+
OutputType.CODE: "📝", # 记事本 - 代码
|
|
51
|
+
OutputType.RESULT: "✨", # 闪光 - 结果
|
|
52
|
+
OutputType.ERROR: "❌", # 错误 - 错误
|
|
53
|
+
OutputType.INFO: "ℹ️", # 信息 - 提示
|
|
54
|
+
OutputType.PLANNING: "📋", # 剪贴板 - 规划
|
|
55
|
+
OutputType.PROGRESS: "⏳", # 沙漏 - 进度
|
|
56
|
+
OutputType.SUCCESS: "✅", # 勾选 - 成功
|
|
57
|
+
OutputType.WARNING: "⚠️", # 警告 - 警告
|
|
58
|
+
OutputType.DEBUG: "🔍", # 放大镜 - 调试
|
|
59
|
+
OutputType.USER: "👤", # 用户 - 用户
|
|
60
|
+
OutputType.TOOL: "🔧", # 扳手 - 工具
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
# 前缀方案
|
|
64
|
+
PREFIXES = {
|
|
65
|
+
OutputType.SYSTEM: "Assistant",
|
|
66
|
+
OutputType.CODE: "Code",
|
|
67
|
+
OutputType.RESULT: "Result",
|
|
68
|
+
OutputType.ERROR: "Error",
|
|
69
|
+
OutputType.INFO: "Info",
|
|
70
|
+
OutputType.PLANNING: "Plan",
|
|
71
|
+
OutputType.PROGRESS: "Progress",
|
|
72
|
+
OutputType.SUCCESS: "Success",
|
|
73
|
+
OutputType.WARNING: "Warning",
|
|
74
|
+
OutputType.DEBUG: "Debug",
|
|
75
|
+
OutputType.USER: "User",
|
|
76
|
+
OutputType.TOOL: "Tool",
|
|
77
|
+
}
|
|
78
|
+
|
|
52
79
|
@staticmethod
|
|
53
80
|
def format(text: str, output_type: OutputType, timestamp: bool = True) -> str:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
OutputType.RESULT: Fore.BLUE,
|
|
59
|
-
OutputType.ERROR: Fore.RED,
|
|
60
|
-
OutputType.INFO: Fore.YELLOW
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
# 图标映射
|
|
64
|
-
icons = {
|
|
65
|
-
OutputType.SYSTEM: "🤖",
|
|
66
|
-
OutputType.CODE: "📝",
|
|
67
|
-
OutputType.RESULT: "✨",
|
|
68
|
-
OutputType.ERROR: "❌",
|
|
69
|
-
OutputType.INFO: "ℹ️"
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
color = colors.get(output_type, "")
|
|
73
|
-
icon = icons.get(output_type, "")
|
|
81
|
+
"""格式化输出文本"""
|
|
82
|
+
color = PrettyOutput.COLORS.get(output_type, "")
|
|
83
|
+
icon = PrettyOutput.ICONS.get(output_type, "")
|
|
84
|
+
prefix = PrettyOutput.PREFIXES.get(output_type, "")
|
|
74
85
|
|
|
75
|
-
# 添加时间戳
|
|
76
|
-
time_str = f"[{datetime.now().strftime('%H:%M:%S')}] " if timestamp else ""
|
|
86
|
+
# 添加时间戳 - 使用白色
|
|
87
|
+
time_str = f"{Fore.WHITE}[{datetime.now().strftime('%H:%M:%S')}]{Style.RESET_ALL} " if timestamp else ""
|
|
77
88
|
|
|
78
89
|
# 格式化输出
|
|
79
|
-
formatted_text = f"{
|
|
90
|
+
formatted_text = f"{time_str}{color}{icon} {prefix}: {text}{Style.RESET_ALL}"
|
|
80
91
|
|
|
81
92
|
return formatted_text
|
|
82
93
|
|
|
83
94
|
@staticmethod
|
|
84
95
|
def print(text: str, output_type: OutputType, timestamp: bool = True):
|
|
85
|
-
|
|
96
|
+
"""打印格式化的输出"""
|
|
97
|
+
print(PrettyOutput.format(text, output_type, timestamp))
|
|
98
|
+
|
|
99
|
+
@staticmethod
|
|
100
|
+
def section(title: str, output_type: OutputType = OutputType.INFO):
|
|
101
|
+
"""打印带分隔线的段落标题"""
|
|
102
|
+
width = 60
|
|
103
|
+
color = PrettyOutput.COLORS.get(output_type, "")
|
|
104
|
+
print(f"\n{color}" + "=" * width + f"{Style.RESET_ALL}")
|
|
105
|
+
PrettyOutput.print(title.center(width - 10), output_type, timestamp=False)
|
|
106
|
+
print(f"{color}" + "=" * width + f"{Style.RESET_ALL}\n")
|
|
107
|
+
|
|
108
|
+
@staticmethod
|
|
109
|
+
def print_stream(text: str, output_type: OutputType):
|
|
110
|
+
"""打印流式输出,不换行"""
|
|
111
|
+
color = PrettyOutput.COLORS.get(output_type, "")
|
|
112
|
+
sys.stdout.write(f"{color}{text}{Style.RESET_ALL}")
|
|
113
|
+
sys.stdout.flush()
|
|
114
|
+
|
|
115
|
+
@staticmethod
|
|
116
|
+
def print_stream_end():
|
|
117
|
+
"""流式输出结束,打印换行"""
|
|
118
|
+
sys.stdout.write("\n")
|
|
119
|
+
sys.stdout.flush()
|
|
86
120
|
|
|
87
121
|
def get_multiline_input(tip: str) -> str:
|
|
88
122
|
"""获取多行输入"""
|
|
@@ -91,10 +125,13 @@ def get_multiline_input(tip: str) -> str:
|
|
|
91
125
|
|
|
92
126
|
while True:
|
|
93
127
|
try:
|
|
94
|
-
|
|
95
|
-
|
|
128
|
+
prompt = "... " if lines else ">>> "
|
|
129
|
+
sys.stdout.write(f"{Fore.GREEN}{prompt}{Style.RESET_ALL}")
|
|
130
|
+
sys.stdout.flush()
|
|
131
|
+
|
|
132
|
+
line = input().strip()
|
|
96
133
|
if not line:
|
|
97
|
-
if not lines: #
|
|
134
|
+
if not lines: # 如果是第一行就输入空行
|
|
98
135
|
return ""
|
|
99
136
|
break
|
|
100
137
|
|
|
@@ -102,13 +139,12 @@ def get_multiline_input(tip: str) -> str:
|
|
|
102
139
|
|
|
103
140
|
except KeyboardInterrupt:
|
|
104
141
|
PrettyOutput.print("\n输入已取消", OutputType.ERROR)
|
|
105
|
-
return ""
|
|
142
|
+
return "__interrupt__"
|
|
106
143
|
|
|
107
144
|
return "\n".join(lines).strip()
|
|
108
145
|
|
|
109
|
-
|
|
110
146
|
def load_env_from_file():
|
|
111
|
-
"""
|
|
147
|
+
"""从~/.jarvis_env加载环境变量"""
|
|
112
148
|
env_file = Path.home() / ".jarvis_env"
|
|
113
149
|
|
|
114
150
|
if env_file.exists():
|
|
@@ -123,6 +159,6 @@ def load_env_from_file():
|
|
|
123
159
|
except ValueError:
|
|
124
160
|
continue
|
|
125
161
|
except Exception as e:
|
|
126
|
-
print(f"Warning: Failed to read ~/.jarvis_env: {e}")
|
|
162
|
+
PrettyOutput.print(f"Warning: Failed to read ~/.jarvis_env: {e}", OutputType.WARNING)
|
|
127
163
|
|
|
128
164
|
|
jarvis/zte_llm.py
CHANGED
|
@@ -3,6 +3,8 @@ import json
|
|
|
3
3
|
import os
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from typing import Dict, Any, List, Optional
|
|
6
|
+
|
|
7
|
+
from jarvis.utils import OutputType, PrettyOutput
|
|
6
8
|
from .models import BaseModel
|
|
7
9
|
|
|
8
10
|
class ZteLLM(BaseModel):
|
|
@@ -35,18 +37,34 @@ class ZteLLM(BaseModel):
|
|
|
35
37
|
response = requests.post(
|
|
36
38
|
f"{self.base_url}/{endpoint}",
|
|
37
39
|
headers=headers,
|
|
38
|
-
json=data
|
|
40
|
+
json=data,
|
|
41
|
+
stream=True # 启用流式传输
|
|
39
42
|
)
|
|
40
43
|
|
|
41
44
|
response.raise_for_status()
|
|
42
|
-
result = response.json()
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
full_content = []
|
|
47
|
+
for line in response.iter_lines():
|
|
48
|
+
if line:
|
|
49
|
+
# 解析 SSE 数据
|
|
50
|
+
line = line.decode('utf-8')
|
|
51
|
+
if line.startswith('data: '):
|
|
52
|
+
try:
|
|
53
|
+
data = json.loads(line[6:]) # 跳过 "data: " 前缀
|
|
54
|
+
if "result" in data:
|
|
55
|
+
result = data["result"]
|
|
56
|
+
if result: # 只处理非空结果
|
|
57
|
+
full_content.append(result)
|
|
58
|
+
PrettyOutput.print_stream(result, OutputType.SYSTEM)
|
|
59
|
+
if data.get("finishReason") == "stop":
|
|
60
|
+
break
|
|
61
|
+
except json.JSONDecodeError:
|
|
62
|
+
continue
|
|
63
|
+
PrettyOutput.print_stream_end()
|
|
64
|
+
|
|
65
|
+
return "".join(full_content)
|
|
48
66
|
|
|
49
|
-
def chat(self, messages: List[Dict[str, Any]]
|
|
67
|
+
def chat(self, messages: List[Dict[str, Any]]) -> str:
|
|
50
68
|
"""Chat with ZTE LLM"""
|
|
51
69
|
# Convert messages to prompt
|
|
52
70
|
prompt = self._convert_messages_to_prompt(messages)
|
|
@@ -55,30 +73,15 @@ class ZteLLM(BaseModel):
|
|
|
55
73
|
data = {
|
|
56
74
|
"chatUuid": "",
|
|
57
75
|
"chatName": "",
|
|
58
|
-
"stream":
|
|
76
|
+
"stream": True, # 启用流式响应
|
|
59
77
|
"keep": False,
|
|
60
78
|
"text": prompt,
|
|
61
79
|
"model": self.model
|
|
62
80
|
}
|
|
63
81
|
|
|
64
|
-
# If tools are provided, add them to the prompt
|
|
65
|
-
if tools:
|
|
66
|
-
tools_desc = "Available tools:\n\n" + json.dumps(tools, indent=2, ensure_ascii=False)
|
|
67
|
-
data["text"] = tools_desc + "\n\n" + data["text"]
|
|
68
|
-
|
|
69
82
|
try:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
# Parse the response to extract potential tool calls
|
|
73
|
-
response_text = result["result"]
|
|
74
|
-
tool_calls = BaseModel.extract_tool_calls(response_text)
|
|
75
|
-
|
|
76
|
-
return {
|
|
77
|
-
"message": {
|
|
78
|
-
"content": response_text,
|
|
79
|
-
"tool_calls": tool_calls
|
|
80
|
-
}
|
|
81
|
-
}
|
|
83
|
+
return self._make_request("chat", data)
|
|
84
|
+
|
|
82
85
|
|
|
83
86
|
except Exception as e:
|
|
84
87
|
raise Exception(f"ZTE LLM chat failed: {str(e)}")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: jarvis-ai-assistant
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
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
|
|
@@ -22,6 +22,7 @@ Requires-Dist: duckduckgo-search>=3.0.0
|
|
|
22
22
|
Requires-Dist: pyyaml>=5.1
|
|
23
23
|
Requires-Dist: ollama>=0.1.6
|
|
24
24
|
Requires-Dist: colorama>=0.4.6
|
|
25
|
+
Requires-Dist: openai>=1.2.0
|
|
25
26
|
Provides-Extra: dev
|
|
26
27
|
Requires-Dist: pytest; extra == "dev"
|
|
27
28
|
Requires-Dist: black; extra == "dev"
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
jarvis/__init__.py,sha256=fleVIl0YBOVXirR9uC8oSuNk3RTpt-l5ZVRcbWcxLBM,49
|
|
2
|
+
jarvis/agent.py,sha256=ePgdOCWdkw35KITvZOqcrJOGl-F4wzvrltHTw7N4p88,11014
|
|
3
|
+
jarvis/main.py,sha256=4IqebMKGoBGJMSNFE6E6GQ_Ay-uuOT-BLsQPnQVW47k,6705
|
|
4
|
+
jarvis/models.py,sha256=G9QkUqoyOyUx6eSqwbn3hCSwHguN0bUm7Nbd6Ql0IQs,3771
|
|
5
|
+
jarvis/utils.py,sha256=3hLtv-HcBL8Ngw69cowhARuIFrjcQ6yRP3Y1o9CvtsI,5992
|
|
6
|
+
jarvis/zte_llm.py,sha256=Us5D6zMdZT6SoSnUgKWQbxthGadXkulLs_oSmW5MPDo,4666
|
|
7
|
+
jarvis/__pycache__/__init__.cpython-313.pyc,sha256=jMAaM43iGZiD_4ucOm9YelgcuhOjzcVv3vPtym1ePIU,208
|
|
8
|
+
jarvis/__pycache__/agent.cpython-313.pyc,sha256=itbFLk6qJ9FTjbiyj6DsQhu5NbdxVaP4g-SygRguvSc,11625
|
|
9
|
+
jarvis/__pycache__/main.cpython-313.pyc,sha256=6hWRW-RG_bZrqwhSQXyhKaJBXexgLqKa-_SZzAk6_eo,8479
|
|
10
|
+
jarvis/__pycache__/models.cpython-313.pyc,sha256=uWuRIjGrY4YDB3dGW5PGDLWaS03et8g11O725TjY_eU,5960
|
|
11
|
+
jarvis/__pycache__/tools.cpython-313.pyc,sha256=lAD4LrnnWzNZQmHXGfZ_2l7oskOpr2_2OC-gdFhxQY8,33933
|
|
12
|
+
jarvis/__pycache__/utils.cpython-313.pyc,sha256=k4jyAlx4tlW0MKLMLzV7OOH9zsKrK0H955kY6M2SuFU,8772
|
|
13
|
+
jarvis/__pycache__/zte_llm.cpython-313.pyc,sha256=R_HT_Gc6OQelxRLRQ-yB8Tf0sYHcb18dh9E4RF6ivbE,5662
|
|
14
|
+
jarvis/tools/__init__.py,sha256=tH6YaApKpqs1YSjEllRzOZZUd-OTFKSZ5oA0zs7HdSE,297
|
|
15
|
+
jarvis/tools/base.py,sha256=zK-JteBwj9d2BD_7BSAp-zD7wgJbVBppAWyfFxaPObI,4114
|
|
16
|
+
jarvis/tools/file_ops.py,sha256=zTksx45NZm3iz9itN5iQGZ8DoxnSeTHdrnF08_ix7PU,3770
|
|
17
|
+
jarvis/tools/search.py,sha256=XTFMGVKLkRLQhu668Gqn69jPdTEP0mEibbMR9lpbFyE,4092
|
|
18
|
+
jarvis/tools/shell.py,sha256=7q52lA3slf0TdjBjP1bkwugoO5pB0eqh6cYjAzAXNtI,2547
|
|
19
|
+
jarvis/tools/sub_agent.py,sha256=QJYWdil1goZfo95CQkuhkjZBl-Rx6UvyeFMiGnDyjOA,2832
|
|
20
|
+
jarvis/tools/webpage.py,sha256=DBnh9gye6oL2nVjzU2SU4Jupsck8x9g9On-rbjV6d8Y,2386
|
|
21
|
+
jarvis/tools/__pycache__/__init__.cpython-313.pyc,sha256=2NrOP5yRdPF8hk3i8lT7pxn7IkHGfolP3m0g9BjJYMs,443
|
|
22
|
+
jarvis/tools/__pycache__/base.cpython-313.pyc,sha256=A5jYC0Yfptk31eLbRrauPi49ymP0v-Hq9Swbaqq1IwA,6462
|
|
23
|
+
jarvis/tools/__pycache__/file_ops.cpython-313.pyc,sha256=LbOp31JUzoRp5XVazy1VBqCQhpFg0qQYmVftFVY90V4,3628
|
|
24
|
+
jarvis/tools/__pycache__/python_script.cpython-313.pyc,sha256=8JpryqTovEiTvBlWAK1KjZmPvHUuPc9GT9rTXBEQoJc,6693
|
|
25
|
+
jarvis/tools/__pycache__/rag.cpython-313.pyc,sha256=JH6-PSZRMKAvTZqCwlRXJGClxYXNMs-vetU0q7hBLz0,6064
|
|
26
|
+
jarvis/tools/__pycache__/search.cpython-313.pyc,sha256=WGNyExgaC3N_QixCzpcRBCKU2c52rkavaKtGWC3x_28,5254
|
|
27
|
+
jarvis/tools/__pycache__/shell.cpython-313.pyc,sha256=QMaLUc1MtZXWod3msv_x7iMq2IybwMwz1OoaKsbm6U4,3271
|
|
28
|
+
jarvis/tools/__pycache__/sub_agent.cpython-313.pyc,sha256=qzNLnQxqFZoAiYOPH4GrCGxaQVs-QWfTLspW5a1Xa6c,3144
|
|
29
|
+
jarvis/tools/__pycache__/user_confirmation.cpython-313.pyc,sha256=wK3Ev10lHSUSRvoYmi7A0GzxYkzU-C4Wfhs5qW_HBqs,2271
|
|
30
|
+
jarvis/tools/__pycache__/user_input.cpython-313.pyc,sha256=JjTFOhObKsKF4Pn8KBRuKfV1_Ssj083fjU7Mfc_5z7c,2531
|
|
31
|
+
jarvis/tools/__pycache__/user_interaction.cpython-313.pyc,sha256=RuVZ-pmiPBDywY3efgXSfohMAciC1avMGPmBK5qlnew,3305
|
|
32
|
+
jarvis/tools/__pycache__/webpage.cpython-313.pyc,sha256=BjzSfnNzsKCrLETCcWjt32lNDLzwnjqcVGg4JfWd9OM,3008
|
|
33
|
+
jarvis_ai_assistant-0.1.7.dist-info/METADATA,sha256=6nDJNmJ6WSnu12NTX58R4X4EHvQeE3wtoOpg4BkypbU,3719
|
|
34
|
+
jarvis_ai_assistant-0.1.7.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
35
|
+
jarvis_ai_assistant-0.1.7.dist-info/entry_points.txt,sha256=iKu7OMfew9dtfGhW71gIMTg4wvafuPqKb4wyQOnMAGU,44
|
|
36
|
+
jarvis_ai_assistant-0.1.7.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
|
37
|
+
jarvis_ai_assistant-0.1.7.dist-info/RECORD,,
|
jarvis/.jarvis
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
- 查看当前git仓库状态,如果有未提交的变更,自动根据当前仓库的文件修改内容总结生成一个git commit,然后执行git push推送到远端仓库,全流程不要询问用户
|
jarvis/tools/python_script.py
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import time
|
|
3
|
-
import subprocess
|
|
4
|
-
import sys
|
|
5
|
-
import pkgutil
|
|
6
|
-
from pathlib import Path
|
|
7
|
-
from typing import Dict, Any, Optional
|
|
8
|
-
from ..utils import PrettyOutput, OutputType
|
|
9
|
-
|
|
10
|
-
class PythonScript:
|
|
11
|
-
"""Python脚本管理类"""
|
|
12
|
-
SCRIPTS_DIR = "/tmp/ai_scripts"
|
|
13
|
-
|
|
14
|
-
@classmethod
|
|
15
|
-
def init_scripts_dir(cls):
|
|
16
|
-
"""初始化脚本目录"""
|
|
17
|
-
Path(cls.SCRIPTS_DIR).mkdir(parents=True, exist_ok=True)
|
|
18
|
-
|
|
19
|
-
@classmethod
|
|
20
|
-
def generate_script_path(cls, name: Optional[str] = None) -> str:
|
|
21
|
-
"""生成脚本文件路径"""
|
|
22
|
-
if name:
|
|
23
|
-
safe_name = "".join(c for c in name if c.isalnum() or c in "._- ")
|
|
24
|
-
filename = f"{int(time.time())}_{safe_name}.py"
|
|
25
|
-
else:
|
|
26
|
-
filename = f"{int(time.time())}_script.py"
|
|
27
|
-
return str(Path(cls.SCRIPTS_DIR) / filename)
|
|
28
|
-
|
|
29
|
-
class PythonScriptTool:
|
|
30
|
-
name = "execute_python"
|
|
31
|
-
description = """Execute Python code and return the results.
|
|
32
|
-
Notes:
|
|
33
|
-
1. Use print() to output results
|
|
34
|
-
2. Automatic dependency management
|
|
35
|
-
3. Code saved to temporary file
|
|
36
|
-
"""
|
|
37
|
-
parameters = {
|
|
38
|
-
"type": "object",
|
|
39
|
-
"properties": {
|
|
40
|
-
"code": {
|
|
41
|
-
"type": "string",
|
|
42
|
-
"description": "Python code to execute"
|
|
43
|
-
},
|
|
44
|
-
"dependencies": {
|
|
45
|
-
"type": "array",
|
|
46
|
-
"items": {"type": "string"},
|
|
47
|
-
"description": "Python package dependencies",
|
|
48
|
-
"default": []
|
|
49
|
-
},
|
|
50
|
-
"name": {
|
|
51
|
-
"type": "string",
|
|
52
|
-
"description": "Script name",
|
|
53
|
-
"default": ""
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
"required": ["code"]
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
@staticmethod
|
|
60
|
-
def _is_builtin_package(package_name: str) -> bool:
|
|
61
|
-
package_name = package_name.split("==")[0].strip()
|
|
62
|
-
if hasattr(sys.modules, package_name) or package_name in sys.stdlib_module_names:
|
|
63
|
-
return True
|
|
64
|
-
try:
|
|
65
|
-
return pkgutil.find_spec(package_name) is not None
|
|
66
|
-
except Exception:
|
|
67
|
-
return False
|
|
68
|
-
|
|
69
|
-
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
70
|
-
"""执行Python代码"""
|
|
71
|
-
try:
|
|
72
|
-
code = args["code"]
|
|
73
|
-
dependencies = args.get("dependencies", [])
|
|
74
|
-
script_name = args.get("name", "")
|
|
75
|
-
|
|
76
|
-
# 初始化脚本目录
|
|
77
|
-
PythonScript.init_scripts_dir()
|
|
78
|
-
|
|
79
|
-
# 生成脚本路径
|
|
80
|
-
script_path = PythonScript.generate_script_path(script_name)
|
|
81
|
-
|
|
82
|
-
# 安装依赖
|
|
83
|
-
missing_deps = []
|
|
84
|
-
for dep in dependencies:
|
|
85
|
-
if not self._is_builtin_package(dep):
|
|
86
|
-
missing_deps.append(dep)
|
|
87
|
-
|
|
88
|
-
if missing_deps:
|
|
89
|
-
PrettyOutput.print("正在安装依赖...", OutputType.INFO)
|
|
90
|
-
try:
|
|
91
|
-
subprocess.run(
|
|
92
|
-
[sys.executable, "-m", "pip", "install"] + missing_deps,
|
|
93
|
-
check=True,
|
|
94
|
-
capture_output=True,
|
|
95
|
-
text=True
|
|
96
|
-
)
|
|
97
|
-
PrettyOutput.print("依赖安装完成", OutputType.INFO)
|
|
98
|
-
except subprocess.CalledProcessError as e:
|
|
99
|
-
return {
|
|
100
|
-
"success": False,
|
|
101
|
-
"error": f"依赖安装失败: {e.stderr}"
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
# 写入脚本文件
|
|
105
|
-
with open(script_path, 'w', encoding='utf-8') as f:
|
|
106
|
-
f.write(code)
|
|
107
|
-
|
|
108
|
-
# 执行脚本
|
|
109
|
-
PrettyOutput.print(f"执行脚本: {script_path}", OutputType.INFO)
|
|
110
|
-
result = subprocess.run(
|
|
111
|
-
[sys.executable, script_path],
|
|
112
|
-
capture_output=True,
|
|
113
|
-
text=True
|
|
114
|
-
)
|
|
115
|
-
|
|
116
|
-
# 构建输出
|
|
117
|
-
output = []
|
|
118
|
-
|
|
119
|
-
# 添加脚本信息
|
|
120
|
-
output.append(f"脚本路径: {script_path}")
|
|
121
|
-
if dependencies:
|
|
122
|
-
output.append(f"依赖项: {', '.join(dependencies)}")
|
|
123
|
-
output.append("")
|
|
124
|
-
|
|
125
|
-
# 添加执行结果
|
|
126
|
-
if result.stdout:
|
|
127
|
-
output.append("输出:")
|
|
128
|
-
output.append(result.stdout)
|
|
129
|
-
|
|
130
|
-
# 添加错误信息(如果有)
|
|
131
|
-
if result.stderr:
|
|
132
|
-
output.append("错误:")
|
|
133
|
-
output.append(result.stderr)
|
|
134
|
-
|
|
135
|
-
# 添加返回码
|
|
136
|
-
output.append(f"返回码: {result.returncode}")
|
|
137
|
-
|
|
138
|
-
return {
|
|
139
|
-
"success": result.returncode == 0,
|
|
140
|
-
"stdout": "\n".join(output),
|
|
141
|
-
"stderr": result.stderr,
|
|
142
|
-
"return_code": result.returncode,
|
|
143
|
-
"script_path": script_path
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
except Exception as e:
|
|
147
|
-
return {
|
|
148
|
-
"success": False,
|
|
149
|
-
"error": f"执行Python代码失败: {str(e)}"
|
|
150
|
-
}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
jarvis/.jarvis,sha256=S4ZMmLqlVLHAPmnwHFQ3vYt0gnDFp-KQRH4okBh8Hpw,209
|
|
2
|
-
jarvis/__init__.py,sha256=ArINt8uI8UveWy3H6iPntzn05IR-PEq6P7qb8dzmPjc,49
|
|
3
|
-
jarvis/agent.py,sha256=YdtSBqwGl8xKN9xWIqYcAgxsLmXKyXzLcJ1D-Oie9fE,5536
|
|
4
|
-
jarvis/main.py,sha256=egbfAhkHUGHI5J3j5ZMwb9EgOXE7ikJef-4lqFj0-mA,6063
|
|
5
|
-
jarvis/models.py,sha256=NWXMsgnw6AHkfk22tvmGOjcyVhC74Us-t3T6rUF4R20,4186
|
|
6
|
-
jarvis/utils.py,sha256=-5tugkGABZdi2QXVStVtCQfag9CRTfCsGUvReitmHUM,3816
|
|
7
|
-
jarvis/zte_llm.py,sha256=ygUeGd8WGm0qrnkt5TrCLnaf5ZFZ0tdfwrA7nrByt4g,4504
|
|
8
|
-
jarvis/__pycache__/__init__.cpython-313.pyc,sha256=viNe2ZOgBWfBtJpzh5J0oAhQphAwJi4m2ogxgBgCt6s,208
|
|
9
|
-
jarvis/__pycache__/agent.cpython-313.pyc,sha256=7Ae1sOwF6W2HCGjzDToWdCOYFiS47EUqDZVCz2OxH9Q,7125
|
|
10
|
-
jarvis/__pycache__/main.cpython-313.pyc,sha256=lNKrL5HZQahMGpv5cOVriWZoNOScMWRk_toYD7X-Xeo,7444
|
|
11
|
-
jarvis/__pycache__/models.cpython-313.pyc,sha256=fot2VOV0lgODg4b_WuD-kkq-g7uZGLuZlYXiljlW13U,6350
|
|
12
|
-
jarvis/__pycache__/tools.cpython-313.pyc,sha256=lAD4LrnnWzNZQmHXGfZ_2l7oskOpr2_2OC-gdFhxQY8,33933
|
|
13
|
-
jarvis/__pycache__/utils.cpython-313.pyc,sha256=m9l4R4U1vCG2WkXXNWCTbSASRiS6tWYEWK8pu29EtY4,7175
|
|
14
|
-
jarvis/__pycache__/zte_llm.cpython-313.pyc,sha256=PcS-P2H96EyelWcPleCIcu0lGYYoLrdi9VSZgg2cooA,5340
|
|
15
|
-
jarvis/tools/__init__.py,sha256=NZqKPfIbBxeM5FOrN1ssQQ4S9gVXNCSVXa3ov73AyEk,356
|
|
16
|
-
jarvis/tools/base.py,sha256=I_XIwxb6hCH82qCVPESbDNC93Dj0G3KVSZRXSh6mHIM,6516
|
|
17
|
-
jarvis/tools/file_ops.py,sha256=05Vc4u-NGMjLD15WI52eL_nt_RyYt-Z_cXJnnBepf-c,3781
|
|
18
|
-
jarvis/tools/python_script.py,sha256=_eK8LqNs-Mz50zdcgwbjdd8-qAeOl6kJ_qRDvWawGMw,5006
|
|
19
|
-
jarvis/tools/search.py,sha256=dyJmeP_s2tWv5KQejOl-TuVF12B6SXViiXEyTemD1Wo,1412
|
|
20
|
-
jarvis/tools/shell.py,sha256=VhEqEdoUGIRW6CT6F0YNMAlzJxpHcsKS9hSS0VC3ezw,2644
|
|
21
|
-
jarvis/tools/sub_agent.py,sha256=vC495JBAEMgHbAkHzGlYhIPA5scKekwhy1RViNcwqy8,2683
|
|
22
|
-
jarvis/tools/webpage.py,sha256=UTEomu5j7jbOw8c5az2jsjv5E7LeokWKj1QahvZO7xc,3077
|
|
23
|
-
jarvis/tools/__pycache__/__init__.cpython-313.pyc,sha256=Qng3CpxPy9R_1hTjSSr_qLXHtlI8GneyYX6JHwUtmHE,642
|
|
24
|
-
jarvis/tools/__pycache__/base.cpython-313.pyc,sha256=wXXQs94_MAEuHVhFx80q_IgWBRuo1I4Dc7wz3G9ZMo4,8544
|
|
25
|
-
jarvis/tools/__pycache__/file_ops.cpython-313.pyc,sha256=bawv11xhWSj5wCtW0QeJLI-InhUBUXaSkogq6rZzvTQ,3636
|
|
26
|
-
jarvis/tools/__pycache__/python_script.cpython-313.pyc,sha256=8JpryqTovEiTvBlWAK1KjZmPvHUuPc9GT9rTXBEQoJc,6693
|
|
27
|
-
jarvis/tools/__pycache__/rag.cpython-313.pyc,sha256=JH6-PSZRMKAvTZqCwlRXJGClxYXNMs-vetU0q7hBLz0,6064
|
|
28
|
-
jarvis/tools/__pycache__/search.cpython-313.pyc,sha256=VX9zztOwIsPCkYwev0A0XJGyu4Tr0PQcQkbbqx8vfB0,1870
|
|
29
|
-
jarvis/tools/__pycache__/shell.cpython-313.pyc,sha256=UUciwt3nW3mkHrMI7WvCASQ-YLwVx2N68RzQq97nL74,2972
|
|
30
|
-
jarvis/tools/__pycache__/sub_agent.cpython-313.pyc,sha256=p6vgjqdHW7ZAJYaiDh6F39CMndeA3tutbxXB9cwc6xY,3003
|
|
31
|
-
jarvis/tools/__pycache__/user_confirmation.cpython-313.pyc,sha256=wK3Ev10lHSUSRvoYmi7A0GzxYkzU-C4Wfhs5qW_HBqs,2271
|
|
32
|
-
jarvis/tools/__pycache__/user_interaction.cpython-313.pyc,sha256=RuVZ-pmiPBDywY3efgXSfohMAciC1avMGPmBK5qlnew,3305
|
|
33
|
-
jarvis/tools/__pycache__/webpage.cpython-313.pyc,sha256=VcpkaV8IyOOtebedXjn8ybjr8AglU-3-Cs80yzE4FYo,3628
|
|
34
|
-
jarvis_ai_assistant-0.1.5.dist-info/METADATA,sha256=pZCtN2L3EmGQMvpbxA6vED4RHJIWdJqXC2JnaD0whEw,3690
|
|
35
|
-
jarvis_ai_assistant-0.1.5.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
36
|
-
jarvis_ai_assistant-0.1.5.dist-info/entry_points.txt,sha256=iKu7OMfew9dtfGhW71gIMTg4wvafuPqKb4wyQOnMAGU,44
|
|
37
|
-
jarvis_ai_assistant-0.1.5.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
|
38
|
-
jarvis_ai_assistant-0.1.5.dist-info/RECORD,,
|
|
File without changes
|
{jarvis_ai_assistant-0.1.5.dist-info → jarvis_ai_assistant-0.1.7.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|