jarvis-ai-assistant 0.1.195__py3-none-any.whl → 0.1.197__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/jarvis_agent/__init__.py +73 -32
- jarvis/jarvis_data/config_schema.json +5 -0
- jarvis/jarvis_utils/config.py +10 -0
- jarvis/jarvis_utils/jarvis_history.py +63 -8
- {jarvis_ai_assistant-0.1.195.dist-info → jarvis_ai_assistant-0.1.197.dist-info}/METADATA +2 -1
- {jarvis_ai_assistant-0.1.195.dist-info → jarvis_ai_assistant-0.1.197.dist-info}/RECORD +11 -11
- {jarvis_ai_assistant-0.1.195.dist-info → jarvis_ai_assistant-0.1.197.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.195.dist-info → jarvis_ai_assistant-0.1.197.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.195.dist-info → jarvis_ai_assistant-0.1.197.dist-info}/licenses/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.195.dist-info → jarvis_ai_assistant-0.1.197.dist-info}/top_level.txt +0 -0
jarvis/__init__.py
CHANGED
jarvis/jarvis_agent/__init__.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
# 标准库导入
|
3
3
|
import datetime
|
4
|
+
import os
|
4
5
|
from pathlib import Path
|
5
6
|
import platform
|
6
7
|
from typing import Any, Callable, Dict, List, Optional, Protocol, Tuple, Union
|
@@ -18,7 +19,7 @@ from jarvis.jarvis_utils.config import (get_data_dir, get_max_token_count,
|
|
18
19
|
get_max_tool_call_count,
|
19
20
|
is_auto_complete,
|
20
21
|
is_execute_tool_confirm,
|
21
|
-
is_use_analysis, is_use_methodology)
|
22
|
+
is_use_analysis, get_history_count, is_use_methodology)
|
22
23
|
from jarvis.jarvis_utils.embedding import get_context_token_count
|
23
24
|
from jarvis.jarvis_utils.globals import (delete_agent, get_interrupt,
|
24
25
|
make_agent_name, set_agent,
|
@@ -159,6 +160,7 @@ class Agent:
|
|
159
160
|
use_methodology: Optional[bool] = None,
|
160
161
|
use_analysis: Optional[bool] = None,
|
161
162
|
files: List[str] = [],
|
163
|
+
history_count: Optional[int] = None,
|
162
164
|
):
|
163
165
|
self.files = files
|
164
166
|
"""初始化Jarvis Agent实例
|
@@ -238,7 +240,11 @@ class Agent:
|
|
238
240
|
self.after_tool_call_cb: Optional[Callable[[Agent], None]] = None
|
239
241
|
|
240
242
|
self.history = JarvisHistory()
|
241
|
-
self.
|
243
|
+
self.history_dir = str(Path(get_data_dir())/"history")
|
244
|
+
self.history.start_record(self.history_dir)
|
245
|
+
|
246
|
+
self.history_count = history_count if history_count is not None else get_history_count()
|
247
|
+
|
242
248
|
|
243
249
|
self.execute_tool_confirm = (
|
244
250
|
execute_tool_confirm
|
@@ -467,13 +473,25 @@ class Agent:
|
|
467
473
|
注意:
|
468
474
|
当上下文长度超过最大值时使用
|
469
475
|
"""
|
470
|
-
|
471
|
-
|
476
|
+
need_summary = True
|
477
|
+
tmp_file_name = ""
|
478
|
+
try:
|
479
|
+
if self.model and self.model.support_upload_files():
|
480
|
+
need_summary = False
|
481
|
+
if need_summary:
|
482
|
+
summary = self.generate_summary()
|
483
|
+
else:
|
484
|
+
import tempfile
|
485
|
+
tmp_file = tempfile.NamedTemporaryFile(delete=False)
|
486
|
+
tmp_file_name = tmp_file.name
|
487
|
+
self.history.save_history(tmp_file_name)
|
488
|
+
self.clear_history() # type: ignore
|
472
489
|
|
473
|
-
|
474
|
-
|
490
|
+
if need_summary:
|
491
|
+
if not summary:
|
492
|
+
return ""
|
475
493
|
|
476
|
-
|
494
|
+
return f"""
|
477
495
|
以下是之前对话的关键信息总结:
|
478
496
|
|
479
497
|
<content>
|
@@ -481,7 +499,15 @@ class Agent:
|
|
481
499
|
</content>
|
482
500
|
|
483
501
|
请基于以上信息继续完成任务。请注意,这是之前对话的摘要,上下文长度已超过限制而被重置。请直接继续任务,无需重复已完成的步骤。如有需要,可以询问用户以获取更多信息。
|
484
|
-
"""
|
502
|
+
"""
|
503
|
+
else:
|
504
|
+
if self.model and self.model.upload_files([tmp_file_name]):
|
505
|
+
return "上传的文件是历史对话信息,请基于历史对话信息继续完成任务。"
|
506
|
+
else:
|
507
|
+
return ""
|
508
|
+
finally:
|
509
|
+
if tmp_file_name:
|
510
|
+
os.remove(tmp_file_name)
|
485
511
|
|
486
512
|
def _call_tools(self, response: str) -> Tuple[bool, Any]:
|
487
513
|
"""调用工具执行响应
|
@@ -782,31 +808,9 @@ arguments:
|
|
782
808
|
set_agent(self.name, self)
|
783
809
|
|
784
810
|
while True:
|
811
|
+
history_md = ""
|
785
812
|
if self.first:
|
786
|
-
|
787
|
-
if self.model and self.model.support_upload_files():
|
788
|
-
if self.use_methodology:
|
789
|
-
if not upload_methodology(self.model, other_files=self.files):
|
790
|
-
if self.files:
|
791
|
-
PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
|
792
|
-
# 上传失败则回退到本地加载
|
793
|
-
msg = self.prompt
|
794
|
-
for handler in self.input_handler:
|
795
|
-
msg, _ = handler(msg, self)
|
796
|
-
self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
|
797
|
-
elif self.files:
|
798
|
-
if not self.model.upload_files(self.files):
|
799
|
-
PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
|
800
|
-
else:
|
801
|
-
if self.files:
|
802
|
-
PrettyOutput.print("不支持上传文件,将忽略文件列表", OutputType.WARNING)
|
803
|
-
if self.use_methodology:
|
804
|
-
msg = self.prompt
|
805
|
-
for handler in self.input_handler:
|
806
|
-
msg, _ = handler(msg, self)
|
807
|
-
self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
|
808
|
-
|
809
|
-
self.first = False
|
813
|
+
history_md = self._first_run()
|
810
814
|
try:
|
811
815
|
current_response = self._call_model(self.prompt, True)
|
812
816
|
self.prompt = ""
|
@@ -849,6 +853,8 @@ arguments:
|
|
849
853
|
return self._complete_task()
|
850
854
|
|
851
855
|
except Exception as e:
|
856
|
+
if history_md:
|
857
|
+
os.remove(history_md)
|
852
858
|
PrettyOutput.print(f"任务失败: {str(e)}", OutputType.ERROR)
|
853
859
|
return f"Task failed: {str(e)}"
|
854
860
|
|
@@ -856,6 +862,41 @@ arguments:
|
|
856
862
|
PrettyOutput.print(f"任务失败: {str(e)}", OutputType.ERROR)
|
857
863
|
return f"Task failed: {str(e)}"
|
858
864
|
|
865
|
+
def _first_run(self):
|
866
|
+
history_md = ""
|
867
|
+
if self.history_count > 0 and self.model and self.model.support_upload_files():
|
868
|
+
import tempfile
|
869
|
+
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
870
|
+
history_md = str(Path(tempfile.gettempdir())/f"{self.name}_history_{timestamp}.md")
|
871
|
+
self.history.export_history_to_markdown(tempfile.gettempdir(), history_md, max_files=self.history_count)
|
872
|
+
self.files.append(history_md)
|
873
|
+
|
874
|
+
# 如果有上传文件,先上传文件
|
875
|
+
if self.model and self.model.support_upload_files():
|
876
|
+
if self.use_methodology:
|
877
|
+
if not upload_methodology(self.model, other_files=self.files):
|
878
|
+
if self.files:
|
879
|
+
PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
|
880
|
+
# 上传失败则回退到本地加载
|
881
|
+
msg = self.prompt
|
882
|
+
for handler in self.input_handler:
|
883
|
+
msg, _ = handler(msg, self)
|
884
|
+
self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
|
885
|
+
elif self.files:
|
886
|
+
if not self.model.upload_files(self.files):
|
887
|
+
PrettyOutput.print("文件上传失败,将忽略文件列表", OutputType.WARNING)
|
888
|
+
else:
|
889
|
+
if self.files:
|
890
|
+
PrettyOutput.print("不支持上传文件,将忽略文件列表", OutputType.WARNING)
|
891
|
+
if self.use_methodology:
|
892
|
+
msg = self.prompt
|
893
|
+
for handler in self.input_handler:
|
894
|
+
msg, _ = handler(msg, self)
|
895
|
+
self.prompt = f"{self.prompt}\n\n以下是历史类似问题的执行经验,可参考:\n{load_methodology(msg, self.get_tool_registry())}"
|
896
|
+
|
897
|
+
self.first = False
|
898
|
+
return history_md
|
899
|
+
|
859
900
|
def clear_history(self):
|
860
901
|
"""清空对话历史但保留系统提示
|
861
902
|
|
@@ -201,6 +201,11 @@
|
|
201
201
|
"description": "是否打印提示",
|
202
202
|
"default": false
|
203
203
|
},
|
204
|
+
"JARVIS_USE_HISTORY_COUNT": {
|
205
|
+
"type": "number",
|
206
|
+
"description": "使用的历史记录数量",
|
207
|
+
"default": 0
|
208
|
+
},
|
204
209
|
"JARVIS_REPLACE_MAP": {
|
205
210
|
"type": "object",
|
206
211
|
"description": "自定义替换映射表配置",
|
jarvis/jarvis_utils/config.py
CHANGED
@@ -265,6 +265,16 @@ def is_print_prompt() -> bool:
|
|
265
265
|
return GLOBAL_CONFIG_DATA.get("JARVIS_PRINT_PROMPT", False) == True
|
266
266
|
|
267
267
|
|
268
|
+
def get_history_count() -> int:
|
269
|
+
"""
|
270
|
+
获取是否启用历史记录功能。
|
271
|
+
|
272
|
+
返回:
|
273
|
+
bool: 如果启用历史记录则返回True,默认为False
|
274
|
+
"""
|
275
|
+
return GLOBAL_CONFIG_DATA.get("JARVIS_USE_HISTORY_COUNT", 0)
|
276
|
+
|
277
|
+
|
268
278
|
def get_mcp_config() -> List[Dict[str, Any]]:
|
269
279
|
"""
|
270
280
|
获取MCP配置列表。
|
@@ -1,6 +1,7 @@
|
|
1
|
+
import glob
|
1
2
|
import os
|
2
3
|
from datetime import datetime
|
3
|
-
from typing import Dict, List, Optional
|
4
|
+
from typing import Dict, List, Optional, Union
|
4
5
|
|
5
6
|
import yaml
|
6
7
|
|
@@ -22,22 +23,76 @@ class JarvisHistory:
|
|
22
23
|
raise RuntimeError("Recording not started. Call start_record first.")
|
23
24
|
self.records.append({"role": role, "message": msg})
|
24
25
|
|
25
|
-
def
|
26
|
+
def save_history(self, filename: str) -> None:
|
26
27
|
"""Save recorded messages to YAML file"""
|
27
|
-
if not self.current_file:
|
28
|
-
raise RuntimeError("No recording session to stop.")
|
29
28
|
|
30
29
|
# Skip saving if records is empty
|
31
30
|
if not self.records:
|
32
|
-
self.current_file = None
|
33
|
-
self.records = []
|
34
31
|
return
|
35
32
|
|
36
33
|
# Ensure directory exists
|
37
|
-
os.makedirs(os.path.dirname(
|
34
|
+
os.makedirs(os.path.dirname(filename), exist_ok=True)
|
38
35
|
|
39
|
-
with open(
|
36
|
+
with open(filename, "w") as f:
|
40
37
|
yaml.safe_dump({"conversation": self.records}, f, allow_unicode=True)
|
41
38
|
|
39
|
+
def stop_record(self) -> None:
|
40
|
+
"""Stop recording session and save messages"""
|
41
|
+
if not self.current_file:
|
42
|
+
raise RuntimeError("No recording session to stop.")
|
43
|
+
|
44
|
+
self.save_history(self.current_file)
|
42
45
|
self.current_file = None
|
43
46
|
self.records = []
|
47
|
+
|
48
|
+
@staticmethod
|
49
|
+
def export_history_to_markdown(
|
50
|
+
input_dir: str, output_file: str, max_files: Optional[int] = None
|
51
|
+
) -> None:
|
52
|
+
"""
|
53
|
+
Export all history files in the directory to a single markdown file
|
54
|
+
|
55
|
+
Args:
|
56
|
+
input_dir: Directory containing history YAML files
|
57
|
+
output_file: Path to output markdown file
|
58
|
+
max_files: Maximum number of history files to export (None for all)
|
59
|
+
"""
|
60
|
+
# Find all history files in the directory
|
61
|
+
history_files = glob.glob(os.path.join(input_dir, "history_*.yaml"))
|
62
|
+
|
63
|
+
if not history_files:
|
64
|
+
raise FileNotFoundError(f"No history files found in {input_dir}")
|
65
|
+
|
66
|
+
# Sort files by modification time (newest first) and limit to max_files
|
67
|
+
history_files.sort(key=os.path.getmtime, reverse=True)
|
68
|
+
if max_files is not None:
|
69
|
+
history_files = history_files[:max_files]
|
70
|
+
|
71
|
+
# Ensure output directory exists
|
72
|
+
os.makedirs(os.path.dirname(output_file), exist_ok=True)
|
73
|
+
|
74
|
+
with open(output_file, "w", encoding="utf-8") as md_file:
|
75
|
+
md_file.write("# Jarvis Conversation History\n\n")
|
76
|
+
|
77
|
+
for history_file in sorted(history_files):
|
78
|
+
# Read YAML file
|
79
|
+
with open(history_file, "r", encoding="utf-8") as f:
|
80
|
+
data = yaml.safe_load(f)
|
81
|
+
|
82
|
+
if not data or "conversation" not in data:
|
83
|
+
continue
|
84
|
+
|
85
|
+
# Write file header with timestamp from filename
|
86
|
+
timestamp = os.path.basename(history_file)[
|
87
|
+
8:-5
|
88
|
+
] # Extract timestamp from "history_YYYYMMDD_HHMMSS.yaml"
|
89
|
+
md_file.write(
|
90
|
+
f"## Conversation at {timestamp[:4]}-{timestamp[4:6]}-{timestamp[6:8]} "
|
91
|
+
f"{timestamp[9:11]}:{timestamp[11:13]}:{timestamp[13:15]}\n\n"
|
92
|
+
)
|
93
|
+
|
94
|
+
# Write conversation messages
|
95
|
+
for msg in data["conversation"]:
|
96
|
+
md_file.write(f"**{msg['role']}**: {msg['message']}\n\n")
|
97
|
+
|
98
|
+
md_file.write("\n---\n\n")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: jarvis-ai-assistant
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.197
|
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
|
@@ -538,6 +538,7 @@ OPENAI_API_BASE: https://api.openai.com/v1
|
|
538
538
|
| `JARVIS_PRINT_PROMPT` | false | 是否打印提示 |
|
539
539
|
| `JARVIS_USE_METHODOLOGY` | true | 是否启用方法论功能 |
|
540
540
|
| `JARVIS_USE_ANALYSIS` | true | 是否启用任务分析功能 |
|
541
|
+
| `JARVIS_USE_HISTORY_COUNT` | 0 | 使用N次历史记录作为上下文记忆 |
|
541
542
|
| `JARVIS_DATA_PATH` | ~/.jarvis | Jarvis数据存储目录路径 |
|
542
543
|
|
543
544
|
## 🛠️ 工具说明 <a id="tools"></a>
|
@@ -1,5 +1,5 @@
|
|
1
|
-
jarvis/__init__.py,sha256=
|
2
|
-
jarvis/jarvis_agent/__init__.py,sha256=
|
1
|
+
jarvis/__init__.py,sha256=yN1aJh6gZYIZoCWOibxj7NWyO48_EH7fOLOVXD_Dl4w,75
|
2
|
+
jarvis/jarvis_agent/__init__.py,sha256=qcer73IfiAd_IaHznBXAg-nzHZdkoCYhRloDFyJRcTM,33346
|
3
3
|
jarvis/jarvis_agent/builtin_input_handler.py,sha256=4CCEtVLRBIpkhDUKd54VcX1JFCIWCvDqDh4B1H-eSn0,2187
|
4
4
|
jarvis/jarvis_agent/jarvis.py,sha256=GH2zi8eXNpW8twiY3LKDEZgGmFC5geB0jlkwFrm7hOQ,6279
|
5
5
|
jarvis/jarvis_agent/main.py,sha256=c6bQe-8LXvW2-NBn9Rn_yPYdrwnkJ8KQaSFY2cPvkxw,2775
|
@@ -29,7 +29,7 @@ jarvis/jarvis_code_analysis/checklists/shell.py,sha256=aRFYhQQvTgbYd-uY5pc8UHIUA
|
|
29
29
|
jarvis/jarvis_code_analysis/checklists/sql.py,sha256=vR0T6qC7b4dURjJVAd7kSVxyvZEQXPG1Jqc2sNTGp5c,2355
|
30
30
|
jarvis/jarvis_code_analysis/checklists/swift.py,sha256=TPx4I6Gupvs6tSerRKmTSKEPQpOLEbH2Y7LXg1uBgxc,2566
|
31
31
|
jarvis/jarvis_code_analysis/checklists/web.py,sha256=25gGD7pDadZQybNFvALYxWvK0VRjGQb1NVJQElwjyk0,3943
|
32
|
-
jarvis/jarvis_data/config_schema.json,sha256=
|
32
|
+
jarvis/jarvis_data/config_schema.json,sha256=yMXCNy8-CRL44r9GKBClvX6LBX20cpm7QOW9TSffAbs,6533
|
33
33
|
jarvis/jarvis_data/huggingface.tar.gz,sha256=dWKnc_tvyx-I_ZkXo91O0b38KxDmLW1ZbmJ3E6fCl_k,1120205
|
34
34
|
jarvis/jarvis_dev/main.py,sha256=zzVDrPQlPJFnHxNjChBAYA8YwIaQYmPxG-bHjIxdL3s,40940
|
35
35
|
jarvis/jarvis_git_details/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -79,20 +79,20 @@ jarvis/jarvis_tools/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
|
|
79
79
|
jarvis/jarvis_tools/cli/main.py,sha256=Mg6TQDxMdzB1Ua1UrZ2EE-uQWsbaeojWaEGHJp2HimA,6375
|
80
80
|
jarvis/jarvis_utils/__init__.py,sha256=67h0ldisGlh3oK4DAeNEL2Bl_VsI3tSmfclasyVlueM,850
|
81
81
|
jarvis/jarvis_utils/builtin_replace_map.py,sha256=s7C5wKhoKkv-O4ltMcDzNpv5oGPC1EbXgiohPHAqksw,4892
|
82
|
-
jarvis/jarvis_utils/config.py,sha256=
|
82
|
+
jarvis/jarvis_utils/config.py,sha256=OomZRIeRHiBntKXdqYP1ArI8aqRFqtMlLkd9-VSd5dA,7364
|
83
83
|
jarvis/jarvis_utils/embedding.py,sha256=suqKOgH4cq2HYj4xvNpqDPN9pyc3hTCl934xYonF6qk,3922
|
84
84
|
jarvis/jarvis_utils/file_processors.py,sha256=XiM248SHS7lLgQDCbORVFWqinbVDUawYxWDOsLXDxP8,3043
|
85
85
|
jarvis/jarvis_utils/git_utils.py,sha256=F1558EbJ3dRl12DMwmT24XjkC8XqddBjhpWxLgyI0aI,15688
|
86
86
|
jarvis/jarvis_utils/globals.py,sha256=9NTMfCVd0jvtloOv14-KE6clhcVStFmyN9jWxLmQ5so,3369
|
87
87
|
jarvis/jarvis_utils/input.py,sha256=WOs9hYSiZE3ao5K-UJmC7KyZByYnC1opHGJTUZm7DVo,7884
|
88
|
-
jarvis/jarvis_utils/jarvis_history.py,sha256=
|
88
|
+
jarvis/jarvis_utils/jarvis_history.py,sha256=Td6cmze9Oc5-Ewz0l9RKYeSg_-fbEu9ZhyEueHEMcLY,3664
|
89
89
|
jarvis/jarvis_utils/methodology.py,sha256=MhPrMxMqElyAn54BDfpQdUqrRr7IbSlrLvAI39LCgTM,8487
|
90
90
|
jarvis/jarvis_utils/output.py,sha256=PRCgudPOB8gMEP3u-g0FGD2c6tBgJhLXUMqNPglfjV8,10813
|
91
91
|
jarvis/jarvis_utils/tag.py,sha256=f211opbbbTcSyzCDwuIK_oCnKhXPNK-RknYyGzY1yD0,431
|
92
92
|
jarvis/jarvis_utils/utils.py,sha256=55kIbFXPFEd6770mdy2fZDh96XH0rIFJw2w3rYhE2Cc,11895
|
93
|
-
jarvis_ai_assistant-0.1.
|
94
|
-
jarvis_ai_assistant-0.1.
|
95
|
-
jarvis_ai_assistant-0.1.
|
96
|
-
jarvis_ai_assistant-0.1.
|
97
|
-
jarvis_ai_assistant-0.1.
|
98
|
-
jarvis_ai_assistant-0.1.
|
93
|
+
jarvis_ai_assistant-0.1.197.dist-info/licenses/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
94
|
+
jarvis_ai_assistant-0.1.197.dist-info/METADATA,sha256=WXBVY2pO7UC4ZppWf6rfgtm61tfqUA3hA0WigWBRs_g,20215
|
95
|
+
jarvis_ai_assistant-0.1.197.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
96
|
+
jarvis_ai_assistant-0.1.197.dist-info/entry_points.txt,sha256=Gy3DOP1PYLMK0GCj4rrP_9lkOyBQ39EK_lKGUSwn41E,869
|
97
|
+
jarvis_ai_assistant-0.1.197.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
98
|
+
jarvis_ai_assistant-0.1.197.dist-info/RECORD,,
|
File without changes
|
{jarvis_ai_assistant-0.1.195.dist-info → jarvis_ai_assistant-0.1.197.dist-info}/entry_points.txt
RENAMED
File without changes
|
{jarvis_ai_assistant-0.1.195.dist-info → jarvis_ai_assistant-0.1.197.dist-info}/licenses/LICENSE
RENAMED
File without changes
|
{jarvis_ai_assistant-0.1.195.dist-info → jarvis_ai_assistant-0.1.197.dist-info}/top_level.txt
RENAMED
File without changes
|