jarvis-ai-assistant 0.1.108__py3-none-any.whl → 0.1.109__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/agent.py +3 -3
- jarvis/jarvis_code_agent/code_agent.py +69 -217
- jarvis/jarvis_code_agent/file_select.py +11 -10
- jarvis/jarvis_code_agent/patch.py +19 -9
- jarvis/jarvis_code_agent/relevant_files.py +1 -162
- jarvis/jarvis_codebase/main.py +52 -57
- jarvis/jarvis_rag/main.py +193 -267
- jarvis/jarvis_tools/registry.py +8 -7
- jarvis/utils.py +151 -12
- {jarvis_ai_assistant-0.1.108.dist-info → jarvis_ai_assistant-0.1.109.dist-info}/METADATA +12 -3
- {jarvis_ai_assistant-0.1.108.dist-info → jarvis_ai_assistant-0.1.109.dist-info}/RECORD +16 -16
- {jarvis_ai_assistant-0.1.108.dist-info → jarvis_ai_assistant-0.1.109.dist-info}/LICENSE +0 -0
- {jarvis_ai_assistant-0.1.108.dist-info → jarvis_ai_assistant-0.1.109.dist-info}/WHEEL +0 -0
- {jarvis_ai_assistant-0.1.108.dist-info → jarvis_ai_assistant-0.1.109.dist-info}/entry_points.txt +0 -0
- {jarvis_ai_assistant-0.1.108.dist-info → jarvis_ai_assistant-0.1.109.dist-info}/top_level.txt +0 -0
jarvis/utils.py
CHANGED
|
@@ -4,7 +4,7 @@ import time
|
|
|
4
4
|
import os
|
|
5
5
|
from enum import Enum
|
|
6
6
|
from datetime import datetime
|
|
7
|
-
from typing import Any, Dict, Optional
|
|
7
|
+
from typing import Any, Dict, List, Optional
|
|
8
8
|
import colorama
|
|
9
9
|
from colorama import Fore, Style as ColoramaStyle
|
|
10
10
|
import numpy as np
|
|
@@ -12,13 +12,14 @@ from prompt_toolkit import PromptSession
|
|
|
12
12
|
from prompt_toolkit.styles import Style as PromptStyle
|
|
13
13
|
from prompt_toolkit.formatted_text import FormattedText
|
|
14
14
|
from sentence_transformers import SentenceTransformer
|
|
15
|
+
from tqdm import tqdm
|
|
15
16
|
from transformers import AutoModelForSequenceClassification, AutoTokenizer
|
|
16
17
|
import torch
|
|
17
18
|
import yaml
|
|
18
19
|
import faiss
|
|
19
20
|
from pygments.lexers import guess_lexer
|
|
20
21
|
from pygments.util import ClassNotFound
|
|
21
|
-
|
|
22
|
+
import psutil
|
|
22
23
|
from rich.console import Console
|
|
23
24
|
from rich.theme import Theme
|
|
24
25
|
from rich.panel import Panel
|
|
@@ -163,7 +164,7 @@ class PrettyOutput:
|
|
|
163
164
|
return formatted
|
|
164
165
|
|
|
165
166
|
@staticmethod
|
|
166
|
-
def print(text: str, output_type: OutputType, timestamp: bool = True, lang: Optional[str] = None):
|
|
167
|
+
def print(text: str, output_type: OutputType, timestamp: bool = True, lang: Optional[str] = None, traceback: bool = False):
|
|
167
168
|
"""Print formatted output using rich console"""
|
|
168
169
|
# Get formatted header
|
|
169
170
|
lang = lang if lang is not None else PrettyOutput._detect_language(text, default_lang='markdown')
|
|
@@ -176,7 +177,7 @@ class PrettyOutput:
|
|
|
176
177
|
console.print(Panel(content, border_style=border_style, title=header, title_align="left", highlight=True))
|
|
177
178
|
|
|
178
179
|
# Print stack trace for errors
|
|
179
|
-
if output_type == OutputType.ERROR:
|
|
180
|
+
if traceback or output_type == OutputType.ERROR:
|
|
180
181
|
console.print_exception()
|
|
181
182
|
|
|
182
183
|
@staticmethod
|
|
@@ -370,6 +371,7 @@ def find_git_root(dir="."):
|
|
|
370
371
|
return ret
|
|
371
372
|
|
|
372
373
|
def has_uncommitted_changes():
|
|
374
|
+
os.system("git add .")
|
|
373
375
|
# Check working directory changes
|
|
374
376
|
working_changes = os.popen("git diff --exit-code").read().strip() != ""
|
|
375
377
|
# Check staged changes
|
|
@@ -398,6 +400,26 @@ def load_embedding_model():
|
|
|
398
400
|
|
|
399
401
|
return embedding_model
|
|
400
402
|
|
|
403
|
+
def load_tokenizer():
|
|
404
|
+
"""Load tokenizer"""
|
|
405
|
+
model_name = "gpt2"
|
|
406
|
+
cache_dir = os.path.expanduser("~/.cache/huggingface/hub")
|
|
407
|
+
|
|
408
|
+
try:
|
|
409
|
+
tokenizer = AutoTokenizer.from_pretrained(
|
|
410
|
+
model_name,
|
|
411
|
+
cache_dir=cache_dir,
|
|
412
|
+
local_files_only=True
|
|
413
|
+
)
|
|
414
|
+
except Exception as e:
|
|
415
|
+
tokenizer = AutoTokenizer.from_pretrained(
|
|
416
|
+
model_name,
|
|
417
|
+
cache_dir=cache_dir,
|
|
418
|
+
local_files_only=False
|
|
419
|
+
)
|
|
420
|
+
|
|
421
|
+
return tokenizer
|
|
422
|
+
|
|
401
423
|
def load_rerank_model():
|
|
402
424
|
"""Load reranking model"""
|
|
403
425
|
model_name = "BAAI/bge-reranker-v2-m3"
|
|
@@ -443,21 +465,21 @@ def is_long_context(files: list) -> bool:
|
|
|
443
465
|
"""Check if the file list belongs to a long context (total characters exceed 80% of the maximum context length)"""
|
|
444
466
|
max_length = get_max_context_length()
|
|
445
467
|
threshold = max_length * 0.8
|
|
446
|
-
|
|
468
|
+
total_tokens = 0
|
|
447
469
|
|
|
448
470
|
for file_path in files:
|
|
449
471
|
try:
|
|
450
472
|
with open(file_path, 'r', encoding='utf-8') as f:
|
|
451
473
|
content = f.read()
|
|
452
|
-
|
|
474
|
+
total_tokens += get_context_token_count(content)
|
|
453
475
|
|
|
454
|
-
if
|
|
476
|
+
if total_tokens > threshold:
|
|
455
477
|
return True
|
|
456
478
|
except Exception as e:
|
|
457
479
|
PrettyOutput.print(f"Failed to read file {file_path}: {e}", OutputType.WARNING)
|
|
458
480
|
continue
|
|
459
481
|
|
|
460
|
-
return
|
|
482
|
+
return total_tokens > threshold
|
|
461
483
|
|
|
462
484
|
|
|
463
485
|
|
|
@@ -586,6 +608,72 @@ def get_file_line_count(filename: str) -> int:
|
|
|
586
608
|
except Exception as e:
|
|
587
609
|
return 0
|
|
588
610
|
|
|
611
|
+
|
|
612
|
+
def init_gpu_config() -> Dict:
|
|
613
|
+
"""Initialize GPU configuration based on available hardware
|
|
614
|
+
|
|
615
|
+
Returns:
|
|
616
|
+
Dict: GPU configuration including memory sizes and availability
|
|
617
|
+
"""
|
|
618
|
+
config = {
|
|
619
|
+
"has_gpu": False,
|
|
620
|
+
"shared_memory": 0,
|
|
621
|
+
"device_memory": 0,
|
|
622
|
+
"memory_fraction": 0.8 # 默认使用80%的可用内存
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
try:
|
|
626
|
+
import torch
|
|
627
|
+
if torch.cuda.is_available():
|
|
628
|
+
# 获取GPU信息
|
|
629
|
+
gpu_mem = torch.cuda.get_device_properties(0).total_memory
|
|
630
|
+
config["has_gpu"] = True
|
|
631
|
+
config["device_memory"] = gpu_mem
|
|
632
|
+
|
|
633
|
+
# 估算共享内存 (通常是系统内存的一部分)
|
|
634
|
+
|
|
635
|
+
system_memory = psutil.virtual_memory().total
|
|
636
|
+
config["shared_memory"] = min(system_memory * 0.5, gpu_mem * 2) # 取系统内存的50%或GPU内存的2倍中的较小值
|
|
637
|
+
|
|
638
|
+
# 设置CUDA内存分配
|
|
639
|
+
torch.cuda.set_per_process_memory_fraction(config["memory_fraction"])
|
|
640
|
+
torch.cuda.empty_cache()
|
|
641
|
+
|
|
642
|
+
PrettyOutput.print(
|
|
643
|
+
f"GPU initialized: {torch.cuda.get_device_name(0)}\n"
|
|
644
|
+
f"Device Memory: {gpu_mem / 1024**3:.1f}GB\n"
|
|
645
|
+
f"Shared Memory: {config['shared_memory'] / 1024**3:.1f}GB",
|
|
646
|
+
output_type=OutputType.SUCCESS
|
|
647
|
+
)
|
|
648
|
+
else:
|
|
649
|
+
PrettyOutput.print("No GPU available, using CPU mode", output_type=OutputType.WARNING)
|
|
650
|
+
except Exception as e:
|
|
651
|
+
PrettyOutput.print(f"GPU initialization failed: {str(e)}", output_type=OutputType.WARNING)
|
|
652
|
+
|
|
653
|
+
return config
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
def get_embedding(embedding_model: Any, text: str) -> np.ndarray:
|
|
657
|
+
"""Get the vector representation of the text"""
|
|
658
|
+
embedding = embedding_model.encode(text,
|
|
659
|
+
normalize_embeddings=True,
|
|
660
|
+
show_progress_bar=False)
|
|
661
|
+
return np.array(embedding, dtype=np.float32)
|
|
662
|
+
|
|
663
|
+
def get_embedding_batch(embedding_model: Any, texts: List[str]) -> np.ndarray:
|
|
664
|
+
"""Get embeddings for a batch of texts efficiently"""
|
|
665
|
+
try:
|
|
666
|
+
all_vectors = []
|
|
667
|
+
for text in texts:
|
|
668
|
+
vectors = get_embedding_with_chunks(embedding_model, text)
|
|
669
|
+
all_vectors.extend(vectors)
|
|
670
|
+
return np.vstack(all_vectors)
|
|
671
|
+
except Exception as e:
|
|
672
|
+
PrettyOutput.print(f"Batch embedding failed: {str(e)}", OutputType.ERROR)
|
|
673
|
+
return np.zeros((0, embedding_model.get_sentence_embedding_dimension()), dtype=np.float32)
|
|
674
|
+
|
|
675
|
+
|
|
676
|
+
|
|
589
677
|
def get_max_context_length():
|
|
590
678
|
return int(os.getenv('JARVIS_MAX_CONTEXT_LENGTH', '131072')) # 默认128k
|
|
591
679
|
|
|
@@ -614,10 +702,7 @@ def get_min_paragraph_length() -> int:
|
|
|
614
702
|
return int(os.getenv('JARVIS_MIN_PARAGRAPH_LENGTH', '50'))
|
|
615
703
|
|
|
616
704
|
def get_max_paragraph_length() -> int:
|
|
617
|
-
return int(os.getenv('JARVIS_MAX_PARAGRAPH_LENGTH', '
|
|
618
|
-
|
|
619
|
-
def get_context_window() -> int:
|
|
620
|
-
return int(os.getenv('JARVIS_CONTEXT_WINDOW', '5'))
|
|
705
|
+
return int(os.getenv('JARVIS_MAX_PARAGRAPH_LENGTH', '12800'))
|
|
621
706
|
|
|
622
707
|
def get_shell_name() -> str:
|
|
623
708
|
return os.getenv('SHELL', 'bash')
|
|
@@ -645,3 +730,57 @@ def get_cheap_platform_name() -> str:
|
|
|
645
730
|
|
|
646
731
|
def get_cheap_model_name() -> str:
|
|
647
732
|
return os.getenv('JARVIS_CHEAP_MODEL', os.getenv('JARVIS_MODEL', 'kimi'))
|
|
733
|
+
|
|
734
|
+
def split_text_into_chunks(text: str, max_length: int = 512) -> List[str]:
|
|
735
|
+
"""Split text into chunks with overlapping windows"""
|
|
736
|
+
chunks = []
|
|
737
|
+
start = 0
|
|
738
|
+
while start < len(text):
|
|
739
|
+
end = start + max_length
|
|
740
|
+
# Find the nearest sentence boundary
|
|
741
|
+
if end < len(text):
|
|
742
|
+
while end > start and text[end] not in {'.', '!', '?', '\n'}:
|
|
743
|
+
end -= 1
|
|
744
|
+
if end == start: # No punctuation found, hard cut
|
|
745
|
+
end = start + max_length
|
|
746
|
+
chunk = text[start:end]
|
|
747
|
+
chunks.append(chunk)
|
|
748
|
+
# Overlap 20% of the window
|
|
749
|
+
start = end - int(max_length * 0.2)
|
|
750
|
+
return chunks
|
|
751
|
+
|
|
752
|
+
def get_embedding_with_chunks(embedding_model: Any, text: str) -> List[np.ndarray]:
|
|
753
|
+
"""Get embeddings for text chunks"""
|
|
754
|
+
chunks = split_text_into_chunks(text, 512)
|
|
755
|
+
if not chunks:
|
|
756
|
+
return []
|
|
757
|
+
|
|
758
|
+
vectors = []
|
|
759
|
+
for chunk in chunks:
|
|
760
|
+
vector = get_embedding(embedding_model, chunk)
|
|
761
|
+
vectors.append(vector)
|
|
762
|
+
return vectors
|
|
763
|
+
|
|
764
|
+
|
|
765
|
+
def get_context_token_count(text: str) -> int:
|
|
766
|
+
"""Get the token count of the text using the tokenizer
|
|
767
|
+
|
|
768
|
+
Args:
|
|
769
|
+
text: The input text to count tokens for
|
|
770
|
+
|
|
771
|
+
Returns:
|
|
772
|
+
int: The number of tokens in the text
|
|
773
|
+
"""
|
|
774
|
+
try:
|
|
775
|
+
# Use a fast tokenizer that's good at general text
|
|
776
|
+
tokenizer = load_tokenizer()
|
|
777
|
+
tokens = tokenizer.encode(text)
|
|
778
|
+
return len(tokens)
|
|
779
|
+
|
|
780
|
+
except Exception as e:
|
|
781
|
+
PrettyOutput.print(f"Error counting tokens: {str(e)}", OutputType.WARNING)
|
|
782
|
+
# Fallback to rough character-based estimate
|
|
783
|
+
return len(text) // 4 # Rough estimate of 4 chars per token
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: jarvis-ai-assistant
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.109
|
|
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
|
|
@@ -58,8 +58,9 @@ Requires-Dist: yaspin>=2.5.0
|
|
|
58
58
|
Requires-Dist: rich>=13.3.1
|
|
59
59
|
Requires-Dist: pygments>=2.15.0
|
|
60
60
|
Requires-Dist: fuzzywuzzy>=0.18.0
|
|
61
|
-
Requires-Dist: python-Levenshtein>=0.
|
|
62
|
-
Requires-Dist: jedi>=0.
|
|
61
|
+
Requires-Dist: python-Levenshtein>=0.25.0
|
|
62
|
+
Requires-Dist: jedi>=0.17.2
|
|
63
|
+
Requires-Dist: psutil>=7.0.0
|
|
63
64
|
Provides-Extra: dev
|
|
64
65
|
Requires-Dist: pytest; extra == "dev"
|
|
65
66
|
Requires-Dist: black; extra == "dev"
|
|
@@ -161,6 +162,14 @@ Jarvis supports configuration through environment variables that can be set in t
|
|
|
161
162
|
| OYI_API_KEY | API key for OYI platform | - | Required for OYI |
|
|
162
163
|
| OLLAMA_API_BASE | Base URL for Ollama API | http://localhost:11434 | No |
|
|
163
164
|
|
|
165
|
+
## Minimal Configuration (Example with OpenAI-compatible Interface)
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
JARVIS_PLATFORM=openai
|
|
169
|
+
JARVIS_MODEL=deepseek-chat
|
|
170
|
+
OPENAI_API_KEY=your_openai_api_key
|
|
171
|
+
OPENAI_API_BASE=https://api.deepseek.com/v1
|
|
172
|
+
```
|
|
164
173
|
|
|
165
174
|
## 🎯 Usage
|
|
166
175
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
jarvis/__init__.py,sha256=
|
|
2
|
-
jarvis/agent.py,sha256=
|
|
3
|
-
jarvis/utils.py,sha256=
|
|
1
|
+
jarvis/__init__.py,sha256=CB3MYpgrHjKZT-LJIoysQYNgLyXYOJSKmxopMqJsAmU,51
|
|
2
|
+
jarvis/agent.py,sha256=x6LmdW5k50nhAK6hdb8V1Vvkt64szwrnaewAto8murg,22690
|
|
3
|
+
jarvis/utils.py,sha256=_GQY1UlxzhKM0DwdnuTUeSmaae8dV83SffsjMPPXFM0,26889
|
|
4
4
|
jarvis/jarvis_code_agent/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
|
-
jarvis/jarvis_code_agent/code_agent.py,sha256=
|
|
6
|
-
jarvis/jarvis_code_agent/file_select.py,sha256=
|
|
7
|
-
jarvis/jarvis_code_agent/patch.py,sha256=
|
|
8
|
-
jarvis/jarvis_code_agent/relevant_files.py,sha256=
|
|
5
|
+
jarvis/jarvis_code_agent/code_agent.py,sha256=nigsmCK6D2z0dFU_1HFNYEvXr3lWdl0rm6p4VgiOk6o,5980
|
|
6
|
+
jarvis/jarvis_code_agent/file_select.py,sha256=1kOVRLPS1GZcDyGpCW9hOPbfCEwF8f0-qVPaRZPHzoM,8154
|
|
7
|
+
jarvis/jarvis_code_agent/patch.py,sha256=bOhegGKs4JEmJJOZfUlmwzGI6kakMyi2Q62HADJ7Npk,4594
|
|
8
|
+
jarvis/jarvis_code_agent/relevant_files.py,sha256=Q4nI45zuyWt5aKuc4OR7-a6UbOXOym3oEzQJvqxkF8Q,946
|
|
9
9
|
jarvis/jarvis_codebase/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
-
jarvis/jarvis_codebase/main.py,sha256=
|
|
10
|
+
jarvis/jarvis_codebase/main.py,sha256=7SwL0QPeojsC95SIlbKjq9FcvKnvPBbtH1kv3SjPUBY,39701
|
|
11
11
|
jarvis/jarvis_lsp/base.py,sha256=_7pdbMKjdtYBW0DsRbjIodDHM3J7df-YgXHejN_WIrU,4490
|
|
12
12
|
jarvis/jarvis_lsp/cpp.py,sha256=F7Zo3BErkvtWS1_H9zQO83pX_FUmnijux-2SjhWzKCE,4985
|
|
13
13
|
jarvis/jarvis_lsp/go.py,sha256=p8LULiFdq4qjDYQzXFlzH0-FQZ3IyfiwN_sbO9i0L_A,5310
|
|
@@ -25,7 +25,7 @@ jarvis/jarvis_platform/registry.py,sha256=9QLoihcnkYckrCzgNnlTqaLn_z_HMhaxMSyUNb
|
|
|
25
25
|
jarvis/jarvis_platform_manager/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
26
26
|
jarvis/jarvis_platform_manager/main.py,sha256=17607aNAStqJ1sOQLTGi6Tnv-cIQme_r5YvbB_S3enc,4985
|
|
27
27
|
jarvis/jarvis_rag/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
28
|
-
jarvis/jarvis_rag/main.py,sha256=
|
|
28
|
+
jarvis/jarvis_rag/main.py,sha256=ZdZZnOyQX8q1mNUeMymb9qg1l77JnG6WBz_KDov0NLQ,31366
|
|
29
29
|
jarvis/jarvis_smart_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
30
30
|
jarvis/jarvis_smart_shell/main.py,sha256=VdUR-x932OccEwU0pcQM_pb_I4yfrAutE3hfm6jf5es,3955
|
|
31
31
|
jarvis/jarvis_tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -51,12 +51,12 @@ jarvis/jarvis_tools/methodology.py,sha256=RFqcVjKuj8ESGmNYcQz_HyphsitDvF3XtqgGaq
|
|
|
51
51
|
jarvis/jarvis_tools/rag.py,sha256=2fQHqc4bw8JM-OxGTsHobLIOTo8Mip3rdtJCmAoY8XU,4952
|
|
52
52
|
jarvis/jarvis_tools/read_code.py,sha256=5DGmeXTgumAiG0RP1xB4sF4NdmBm5BEGjRRlIBzjGnQ,4002
|
|
53
53
|
jarvis/jarvis_tools/read_webpage.py,sha256=JCReSXhkDHDkQ606sZYIKG1Itlprjpmu1sSbF-Ed-jI,2478
|
|
54
|
-
jarvis/jarvis_tools/registry.py,sha256=
|
|
54
|
+
jarvis/jarvis_tools/registry.py,sha256=mYx7q78BQ9El68c6DPbbeMyRp0Dr9GnZoozjhSViLPo,11859
|
|
55
55
|
jarvis/jarvis_tools/search.py,sha256=PLSSNETyajpqDoStCTfkoy-D41IMNudTuVzonMlT6Aw,9225
|
|
56
56
|
jarvis/jarvis_tools/select_code_files.py,sha256=bjJGwCNw0Ue_8jW60K1gcy1rUgKqoHihicu5SS58WNk,1890
|
|
57
|
-
jarvis_ai_assistant-0.1.
|
|
58
|
-
jarvis_ai_assistant-0.1.
|
|
59
|
-
jarvis_ai_assistant-0.1.
|
|
60
|
-
jarvis_ai_assistant-0.1.
|
|
61
|
-
jarvis_ai_assistant-0.1.
|
|
62
|
-
jarvis_ai_assistant-0.1.
|
|
57
|
+
jarvis_ai_assistant-0.1.109.dist-info/LICENSE,sha256=AGgVgQmTqFvaztRtCAXsAMryUymB18gZif7_l2e1XOg,1063
|
|
58
|
+
jarvis_ai_assistant-0.1.109.dist-info/METADATA,sha256=pxorU-ZxDXj6dNQOZfIh285QvRa9hUxXmKGVbgotBTc,14392
|
|
59
|
+
jarvis_ai_assistant-0.1.109.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
60
|
+
jarvis_ai_assistant-0.1.109.dist-info/entry_points.txt,sha256=UYj4FYvOH8jJ0GgCJTA_TAmJ3wvikos-hUVbCwt_KOc,480
|
|
61
|
+
jarvis_ai_assistant-0.1.109.dist-info/top_level.txt,sha256=1BOxyWfzOP_ZXj8rVTDnNCJ92bBGB0rwq8N1PCpoMIs,7
|
|
62
|
+
jarvis_ai_assistant-0.1.109.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
{jarvis_ai_assistant-0.1.108.dist-info → jarvis_ai_assistant-0.1.109.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{jarvis_ai_assistant-0.1.108.dist-info → jarvis_ai_assistant-0.1.109.dist-info}/top_level.txt
RENAMED
|
File without changes
|