jarvis-ai-assistant 0.1.9__py3-none-any.whl → 0.1.11__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/__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__/zte_llm.cpython-313.pyc +0 -0
- jarvis/agent.py +93 -150
- jarvis/main.py +14 -89
- jarvis/models/__init__.py +11 -0
- jarvis/models/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/base.cpython-313.pyc +0 -0
- jarvis/models/__pycache__/kimi.cpython-313.pyc +0 -0
- jarvis/models/base.py +19 -0
- jarvis/models/kimi.py +258 -0
- jarvis/tools/__init__.py +0 -4
- jarvis/tools/__pycache__/__init__.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/base.cpython-313.pyc +0 -0
- jarvis/tools/__pycache__/sub_agent.cpython-313.pyc +0 -0
- jarvis/tools/base.py +0 -6
- {jarvis_ai_assistant-0.1.9.dist-info → jarvis_ai_assistant-0.1.11.dist-info}/METADATA +1 -6
- jarvis_ai_assistant-0.1.11.dist-info/RECORD +39 -0
- jarvis/models.py +0 -122
- jarvis/tools/bing_search.py +0 -38
- jarvis/tools/search.py +0 -132
- jarvis/tools/sub_agent.py +0 -83
- jarvis/tools/webpage.py +0 -76
- jarvis/zte_llm.py +0 -135
- jarvis_ai_assistant-0.1.9.dist-info/RECORD +0 -39
- {jarvis_ai_assistant-0.1.9.dist-info → jarvis_ai_assistant-0.1.11.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.9.dist-info → jarvis_ai_assistant-0.1.11.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.9.dist-info → jarvis_ai_assistant-0.1.11.dist-info}/top_level.txt +0 -0
jarvis/tools/sub_agent.py
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
from typing import Dict, Any
|
|
2
|
-
from ..agent import Agent
|
|
3
|
-
from ..models import BaseModel
|
|
4
|
-
from ..utils import PrettyOutput, OutputType
|
|
5
|
-
from .base import ToolRegistry
|
|
6
|
-
|
|
7
|
-
class SubAgentTool:
|
|
8
|
-
name = "create_sub_agent"
|
|
9
|
-
description = """创建一个子代理来处理独立任务。(重要:子代理启动时没有任何上下文!必须提供完整的步骤和上下文。)"""
|
|
10
|
-
|
|
11
|
-
parameters = {
|
|
12
|
-
"type": "object",
|
|
13
|
-
"properties": {
|
|
14
|
-
"name": {
|
|
15
|
-
"type": "string",
|
|
16
|
-
"description": "子代理名称(例如:'文件分析器')"
|
|
17
|
-
},
|
|
18
|
-
"task": {
|
|
19
|
-
"type": "string",
|
|
20
|
-
"description": "需要明确步骤和目标的任务"
|
|
21
|
-
},
|
|
22
|
-
"context": {
|
|
23
|
-
"type": "string",
|
|
24
|
-
"description": "必填:背景信息、执行步骤和预期结果",
|
|
25
|
-
"default": ""
|
|
26
|
-
}
|
|
27
|
-
},
|
|
28
|
-
"required": ["name", "task", "context"]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
def __init__(self, model: BaseModel):
|
|
32
|
-
"""Initialize with the same model as parent agent"""
|
|
33
|
-
self.model = model
|
|
34
|
-
|
|
35
|
-
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
36
|
-
"""Create and run a sub-agent for the specified task"""
|
|
37
|
-
try:
|
|
38
|
-
name = args["name"]
|
|
39
|
-
task = args["task"]
|
|
40
|
-
context = args.get("context")
|
|
41
|
-
|
|
42
|
-
if not context:
|
|
43
|
-
return {
|
|
44
|
-
"success": False,
|
|
45
|
-
"error": "必须提供上下文信息,包括完整的背景和执行步骤。"
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
PrettyOutput.print(f"正在创建子代理 '{name}'...", OutputType.INFO)
|
|
49
|
-
|
|
50
|
-
# Create a new tool registry for the sub-agent
|
|
51
|
-
tool_registry = ToolRegistry(self.model)
|
|
52
|
-
|
|
53
|
-
# Create the sub-agent with the specified name
|
|
54
|
-
sub_agent = Agent(self.model, tool_registry, name=name, is_sub_agent=True)
|
|
55
|
-
|
|
56
|
-
# Prepare the task with context
|
|
57
|
-
full_task = f"""背景和步骤:
|
|
58
|
-
{context}
|
|
59
|
-
|
|
60
|
-
主要任务:
|
|
61
|
-
{task}
|
|
62
|
-
|
|
63
|
-
要求:
|
|
64
|
-
1. 严格按照提供的步骤执行
|
|
65
|
-
2. 每完成一个步骤都要报告进度
|
|
66
|
-
3. 突出显示任何问题或不明确的点
|
|
67
|
-
4. 提供符合预期输出的详细结果"""
|
|
68
|
-
|
|
69
|
-
PrettyOutput.print(f"子代理 '{name}' 正在执行任务...", OutputType.INFO)
|
|
70
|
-
|
|
71
|
-
# Execute the task and get the summary
|
|
72
|
-
summary = sub_agent.run(full_task)
|
|
73
|
-
return {
|
|
74
|
-
"success": True,
|
|
75
|
-
"stdout": f"子代理 '{name}' 已完成。\n\n结果:\n{summary}",
|
|
76
|
-
"stderr": ""
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
except Exception as e:
|
|
80
|
-
return {
|
|
81
|
-
"success": False,
|
|
82
|
-
"error": f"子代理执行失败:{str(e)}"
|
|
83
|
-
}
|
jarvis/tools/webpage.py
DELETED
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
from typing import Dict, Any
|
|
2
|
-
import requests
|
|
3
|
-
from bs4 import BeautifulSoup
|
|
4
|
-
from ..utils import PrettyOutput, OutputType
|
|
5
|
-
|
|
6
|
-
class WebpageTool:
|
|
7
|
-
name = "read_webpage"
|
|
8
|
-
description = "读取网页内容,提取标题和正文文本"
|
|
9
|
-
parameters = {
|
|
10
|
-
"type": "object",
|
|
11
|
-
"properties": {
|
|
12
|
-
"url": {
|
|
13
|
-
"type": "string",
|
|
14
|
-
"description": "需要读取的网页URL"
|
|
15
|
-
}
|
|
16
|
-
},
|
|
17
|
-
"required": ["url"]
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
def execute(self, args: Dict) -> Dict[str, Any]:
|
|
21
|
-
"""读取网页内容"""
|
|
22
|
-
try:
|
|
23
|
-
url = args["url"]
|
|
24
|
-
|
|
25
|
-
# 设置请求头
|
|
26
|
-
headers = {
|
|
27
|
-
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
# 发送请求
|
|
31
|
-
PrettyOutput.print(f"正在读取网页: {url}", OutputType.INFO)
|
|
32
|
-
response = requests.get(url, headers=headers, timeout=10)
|
|
33
|
-
response.raise_for_status()
|
|
34
|
-
|
|
35
|
-
# 使用正确的编码
|
|
36
|
-
response.encoding = response.apparent_encoding
|
|
37
|
-
|
|
38
|
-
# 解析HTML
|
|
39
|
-
soup = BeautifulSoup(response.text, 'html.parser')
|
|
40
|
-
|
|
41
|
-
# 移除script和style标签
|
|
42
|
-
for script in soup(["script", "style"]):
|
|
43
|
-
script.decompose()
|
|
44
|
-
|
|
45
|
-
# 提取标题
|
|
46
|
-
title = soup.title.string if soup.title else ""
|
|
47
|
-
title = title.strip() if title else "无标题"
|
|
48
|
-
|
|
49
|
-
# 提取正文
|
|
50
|
-
text = soup.get_text(separator='\n', strip=True)
|
|
51
|
-
lines = [line.strip() for line in text.splitlines() if line.strip()]
|
|
52
|
-
|
|
53
|
-
# 构建输出
|
|
54
|
-
output = [
|
|
55
|
-
f"标题: {title}",
|
|
56
|
-
"",
|
|
57
|
-
"正文内容:",
|
|
58
|
-
"\n".join(lines)
|
|
59
|
-
]
|
|
60
|
-
|
|
61
|
-
return {
|
|
62
|
-
"success": True,
|
|
63
|
-
"stdout": "\n".join(output),
|
|
64
|
-
"stderr": ""
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
except requests.RequestException as e:
|
|
68
|
-
return {
|
|
69
|
-
"success": False,
|
|
70
|
-
"error": f"网页请求失败: {str(e)}"
|
|
71
|
-
}
|
|
72
|
-
except Exception as e:
|
|
73
|
-
return {
|
|
74
|
-
"success": False,
|
|
75
|
-
"error": f"解析网页失败: {str(e)}"
|
|
76
|
-
}
|
jarvis/zte_llm.py
DELETED
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
import requests
|
|
2
|
-
import json
|
|
3
|
-
import os
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import Dict, Any, List, Optional
|
|
6
|
-
|
|
7
|
-
from jarvis.utils import OutputType, PrettyOutput
|
|
8
|
-
from .models import BaseModel
|
|
9
|
-
|
|
10
|
-
class ZteLLM(BaseModel):
|
|
11
|
-
"""ZTE Nebula LLM implementation"""
|
|
12
|
-
|
|
13
|
-
def __init__(self,
|
|
14
|
-
app_id: str,
|
|
15
|
-
app_key: str,
|
|
16
|
-
emp_no: str,
|
|
17
|
-
auth_value: str,
|
|
18
|
-
model: str = "nebulacoder",
|
|
19
|
-
):
|
|
20
|
-
"""Initialize ZTE LLM with required credentials"""
|
|
21
|
-
self.app_id = str(app_id)
|
|
22
|
-
self.app_key = str(app_key)
|
|
23
|
-
self.emp_no = str(emp_no)
|
|
24
|
-
self.auth_value = str(auth_value)
|
|
25
|
-
self.model = model
|
|
26
|
-
self.base_url = "https://studio.zte.com.cn/zte-studio-ai-platform/openapi/v1"
|
|
27
|
-
|
|
28
|
-
def _make_request(self, endpoint: str, data: Dict[str, Any]) -> Dict[str, Any]:
|
|
29
|
-
"""Make request to ZTE API"""
|
|
30
|
-
headers = {
|
|
31
|
-
'Content-Type': 'application/json',
|
|
32
|
-
'Authorization': f'Bearer {self.app_id}-{self.app_key}',
|
|
33
|
-
'X-Emp-No': self.emp_no,
|
|
34
|
-
'X-Auth-Value': self.auth_value
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
response = requests.post(
|
|
38
|
-
f"{self.base_url}/{endpoint}",
|
|
39
|
-
headers=headers,
|
|
40
|
-
json=data,
|
|
41
|
-
stream=True # 启用流式传输
|
|
42
|
-
)
|
|
43
|
-
|
|
44
|
-
response.raise_for_status()
|
|
45
|
-
|
|
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)
|
|
66
|
-
|
|
67
|
-
def chat(self, messages: List[Dict[str, Any]]) -> str:
|
|
68
|
-
"""Chat with ZTE LLM"""
|
|
69
|
-
# Convert messages to prompt
|
|
70
|
-
prompt = self._convert_messages_to_prompt(messages)
|
|
71
|
-
|
|
72
|
-
# Prepare data for API call
|
|
73
|
-
data = {
|
|
74
|
-
"chatUuid": "",
|
|
75
|
-
"chatName": "",
|
|
76
|
-
"stream": True, # 启用流式响应
|
|
77
|
-
"keep": False,
|
|
78
|
-
"text": prompt,
|
|
79
|
-
"model": self.model
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
try:
|
|
83
|
-
return self._make_request("chat", data)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
except Exception as e:
|
|
87
|
-
raise Exception(f"ZTE LLM chat failed: {str(e)}")
|
|
88
|
-
|
|
89
|
-
def _convert_messages_to_prompt(self, messages: List[Dict[str, Any]]) -> str:
|
|
90
|
-
"""Convert message list to a single prompt string"""
|
|
91
|
-
prompt_parts = []
|
|
92
|
-
|
|
93
|
-
for message in messages:
|
|
94
|
-
role = message["role"]
|
|
95
|
-
content = message.get("content", "")
|
|
96
|
-
|
|
97
|
-
if role == "system":
|
|
98
|
-
prompt_parts.append(f"System: {content}")
|
|
99
|
-
elif role == "user":
|
|
100
|
-
prompt_parts.append(f"User: {content}")
|
|
101
|
-
elif role == "assistant":
|
|
102
|
-
prompt_parts.append(f"Assistant: {content}")
|
|
103
|
-
elif role == "tool":
|
|
104
|
-
prompt_parts.append(f"Tool Result: {content}")
|
|
105
|
-
|
|
106
|
-
return "\n\n".join(prompt_parts)
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
def create_zte_llm(model_name: str = "NebulaBiz") -> ZteLLM:
|
|
110
|
-
"""Create ZTE LLM instance with provided parameters"""
|
|
111
|
-
# Load environment variables from file
|
|
112
|
-
|
|
113
|
-
# Get credentials from parameters, env file, or system environment variables
|
|
114
|
-
app_id = os.getenv('ZTE_APP_ID')
|
|
115
|
-
app_key = os.getenv('ZTE_APP_KEY')
|
|
116
|
-
emp_no = os.getenv('ZTE_EMP_NO')
|
|
117
|
-
auth_value = os.getenv('ZTE_AUTH_VALUE')
|
|
118
|
-
|
|
119
|
-
# Validate required credentials
|
|
120
|
-
if not all([app_id, app_key, emp_no, auth_value]):
|
|
121
|
-
raise ValueError(
|
|
122
|
-
"Missing required credentials. Please provide through either:\n"
|
|
123
|
-
"1. Function parameters\n"
|
|
124
|
-
"2. ~/.jarvis_env file\n"
|
|
125
|
-
"3. System environment variables\n\n"
|
|
126
|
-
"Required variables: ZTE_APP_ID, ZTE_APP_KEY, ZTE_EMP_NO, ZTE_AUTH_VALUE"
|
|
127
|
-
)
|
|
128
|
-
|
|
129
|
-
return ZteLLM(
|
|
130
|
-
app_id=app_id,
|
|
131
|
-
app_key=app_key,
|
|
132
|
-
emp_no=emp_no,
|
|
133
|
-
auth_value=auth_value,
|
|
134
|
-
model=model_name
|
|
135
|
-
)
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
jarvis/__init__.py,sha256=-pqI_MJPVrCN3BBcW2YIg8KbW5B7vfbpb-ESMyNKpVg,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=GF-b9JNTGgyKROLNqZojLYFIrgPShHKlZADEFHP_YfE,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/bing_search.py,sha256=SvYeXM83eP9qREDcWguh0_r0m0npbcwXIyzEwwfreKU,1444
|
|
17
|
-
jarvis/tools/file_ops.py,sha256=zTksx45NZm3iz9itN5iQGZ8DoxnSeTHdrnF08_ix7PU,3770
|
|
18
|
-
jarvis/tools/search.py,sha256=P4vEbwcXTP6gpc4nwLEuERX0vVszGaer9xvaLfFI0Uc,4836
|
|
19
|
-
jarvis/tools/shell.py,sha256=7q52lA3slf0TdjBjP1bkwugoO5pB0eqh6cYjAzAXNtI,2547
|
|
20
|
-
jarvis/tools/sub_agent.py,sha256=QJYWdil1goZfo95CQkuhkjZBl-Rx6UvyeFMiGnDyjOA,2832
|
|
21
|
-
jarvis/tools/webpage.py,sha256=DBnh9gye6oL2nVjzU2SU4Jupsck8x9g9On-rbjV6d8Y,2386
|
|
22
|
-
jarvis/tools/__pycache__/__init__.cpython-313.pyc,sha256=1d1eUI0FlaydGB8TFBln6s7cBKd6gcPdER2_DIfX2Aw,443
|
|
23
|
-
jarvis/tools/__pycache__/base.cpython-313.pyc,sha256=2OJWYNsGJjKJs6Vdj9NcN_Snjd2bA_OLlB-zr2j4wfs,6462
|
|
24
|
-
jarvis/tools/__pycache__/bing_search.cpython-313.pyc,sha256=1G_wPbk5wcQYh7H0drLIS2Aw0XOG2ZM8ztgfQaqu3P8,2031
|
|
25
|
-
jarvis/tools/__pycache__/file_ops.cpython-313.pyc,sha256=LbOp31JUzoRp5XVazy1VBqCQhpFg0qQYmVftFVY90V4,3628
|
|
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=wLMIkFwT-h4NGHgssytT4xme7sGO6ZhEnex7kjcy0-k,5990
|
|
29
|
-
jarvis/tools/__pycache__/shell.cpython-313.pyc,sha256=QMaLUc1MtZXWod3msv_x7iMq2IybwMwz1OoaKsbm6U4,3271
|
|
30
|
-
jarvis/tools/__pycache__/sub_agent.cpython-313.pyc,sha256=qzNLnQxqFZoAiYOPH4GrCGxaQVs-QWfTLspW5a1Xa6c,3144
|
|
31
|
-
jarvis/tools/__pycache__/user_confirmation.cpython-313.pyc,sha256=wK3Ev10lHSUSRvoYmi7A0GzxYkzU-C4Wfhs5qW_HBqs,2271
|
|
32
|
-
jarvis/tools/__pycache__/user_input.cpython-313.pyc,sha256=JjTFOhObKsKF4Pn8KBRuKfV1_Ssj083fjU7Mfc_5z7c,2531
|
|
33
|
-
jarvis/tools/__pycache__/user_interaction.cpython-313.pyc,sha256=RuVZ-pmiPBDywY3efgXSfohMAciC1avMGPmBK5qlnew,3305
|
|
34
|
-
jarvis/tools/__pycache__/webpage.cpython-313.pyc,sha256=BjzSfnNzsKCrLETCcWjt32lNDLzwnjqcVGg4JfWd9OM,3008
|
|
35
|
-
jarvis_ai_assistant-0.1.9.dist-info/METADATA,sha256=d5LRsaxuZB6V0m8klCq07sxghlARFo7K8VM36TyCnvk,3753
|
|
36
|
-
jarvis_ai_assistant-0.1.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
37
|
-
jarvis_ai_assistant-0.1.9.dist-info/entry_points.txt,sha256=iKu7OMfew9dtfGhW71gIMTg4wvafuPqKb4wyQOnMAGU,44
|
|
38
|
-
jarvis_ai_assistant-0.1.9.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
|
39
|
-
jarvis_ai_assistant-0.1.9.dist-info/RECORD,,
|
|
File without changes
|
{jarvis_ai_assistant-0.1.9.dist-info → jarvis_ai_assistant-0.1.11.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|