nexaai 1.0.7__cp310-cp310-macosx_13_0_x86_64.whl → 1.0.8__cp310-cp310-macosx_13_0_x86_64.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 nexaai might be problematic. Click here for more details.
- nexaai/_stub.cpython-310-darwin.so +0 -0
- nexaai/_version.py +1 -1
- nexaai/binds/libnexa_bridge.dylib +0 -0
- nexaai/utils/model_manager.py +59 -34
- nexaai/utils/progress_tracker.py +2 -2
- {nexaai-1.0.7.dist-info → nexaai-1.0.8.dist-info}/METADATA +1 -1
- {nexaai-1.0.7.dist-info → nexaai-1.0.8.dist-info}/RECORD +9 -9
- {nexaai-1.0.7.dist-info → nexaai-1.0.8.dist-info}/WHEEL +0 -0
- {nexaai-1.0.7.dist-info → nexaai-1.0.8.dist-info}/top_level.txt +0 -0
|
Binary file
|
nexaai/_version.py
CHANGED
|
Binary file
|
nexaai/utils/model_manager.py
CHANGED
|
@@ -14,6 +14,7 @@ from .progress_tracker import CustomProgressTqdm, DownloadProgressTracker
|
|
|
14
14
|
from .avatar_fetcher import get_avatar_url_for_repo
|
|
15
15
|
from .manifest_utils import (
|
|
16
16
|
load_download_metadata,
|
|
17
|
+
save_download_metadata,
|
|
17
18
|
save_manifest_with_files_metadata,
|
|
18
19
|
)
|
|
19
20
|
|
|
@@ -117,6 +118,13 @@ def _get_directory_size_and_files(directory_path: str) -> tuple[int, List[str]]:
|
|
|
117
118
|
return total_size, files
|
|
118
119
|
|
|
119
120
|
|
|
121
|
+
def _has_valid_metadata(directory_path: str) -> bool:
|
|
122
|
+
"""Check if directory has either nexa.manifest or download_metadata.json (for backward compatibility)."""
|
|
123
|
+
manifest_path = os.path.join(directory_path, 'nexa.manifest')
|
|
124
|
+
old_metadata_path = os.path.join(directory_path, 'download_metadata.json')
|
|
125
|
+
return os.path.exists(manifest_path) or os.path.exists(old_metadata_path)
|
|
126
|
+
|
|
127
|
+
|
|
120
128
|
def _scan_for_repo_folders(base_path: str) -> List[DownloadedModel]:
|
|
121
129
|
"""Scan a directory for repository folders and return model information."""
|
|
122
130
|
models = []
|
|
@@ -142,9 +150,8 @@ def _scan_for_repo_folders(base_path: str) -> List[DownloadedModel]:
|
|
|
142
150
|
if os.path.isdir(subitem_path):
|
|
143
151
|
has_subdirs = True
|
|
144
152
|
# This looks like owner/repo structure
|
|
145
|
-
# Only include if nexa.manifest exists
|
|
146
|
-
|
|
147
|
-
if os.path.exists(manifest_path):
|
|
153
|
+
# Only include if nexa.manifest or download_metadata.json exists (backward compatibility)
|
|
154
|
+
if _has_valid_metadata(subitem_path):
|
|
148
155
|
size_bytes, files = _get_directory_size_and_files(subitem_path)
|
|
149
156
|
if files: # Only include if there are files
|
|
150
157
|
# Check if the download is complete
|
|
@@ -172,9 +179,8 @@ def _scan_for_repo_folders(base_path: str) -> List[DownloadedModel]:
|
|
|
172
179
|
|
|
173
180
|
# Direct repo folder (no owner structure)
|
|
174
181
|
if not has_subdirs and direct_files:
|
|
175
|
-
# Only include if nexa.manifest exists
|
|
176
|
-
|
|
177
|
-
if os.path.exists(manifest_path):
|
|
182
|
+
# Only include if nexa.manifest or download_metadata.json exists (backward compatibility)
|
|
183
|
+
if _has_valid_metadata(item_path):
|
|
178
184
|
size_bytes, files = _get_directory_size_and_files(item_path)
|
|
179
185
|
if files: # Only include if there are files
|
|
180
186
|
# Check if the download is complete
|
|
@@ -723,38 +729,57 @@ class HuggingFaceDownloader:
|
|
|
723
729
|
|
|
724
730
|
def _fetch_and_save_metadata(self, repo_id: str, local_dir: str) -> None:
|
|
725
731
|
"""Fetch model info and save metadata after successful download."""
|
|
732
|
+
# Initialize metadata with defaults to ensure manifest is always created
|
|
733
|
+
old_metadata = {
|
|
734
|
+
'pipeline_tag': None,
|
|
735
|
+
'download_time': datetime.now().isoformat(),
|
|
736
|
+
'avatar_url': None
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
# Try to fetch additional metadata, but don't let failures prevent manifest creation
|
|
726
740
|
try:
|
|
727
741
|
# Fetch model info to get pipeline_tag
|
|
728
742
|
info = self.api.model_info(repo_id, token=self.token)
|
|
729
|
-
|
|
730
|
-
|
|
743
|
+
if hasattr(info, 'pipeline_tag'):
|
|
744
|
+
old_metadata['pipeline_tag'] = info.pipeline_tag
|
|
745
|
+
except Exception as e:
|
|
746
|
+
# Log the error but continue with manifest creation
|
|
747
|
+
print(f"Warning: Could not fetch model info for {repo_id}: {e}")
|
|
748
|
+
|
|
749
|
+
try:
|
|
731
750
|
# Get avatar URL
|
|
732
751
|
avatar_url = get_avatar_url_for_repo(repo_id, custom_endpoint=self.endpoint)
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
# Get list of files in the directory
|
|
742
|
-
files = []
|
|
743
|
-
try:
|
|
744
|
-
for root, dirs, filenames in os.walk(local_dir):
|
|
745
|
-
for filename in filenames:
|
|
746
|
-
# Store relative path from the directory
|
|
747
|
-
rel_path = os.path.relpath(os.path.join(root, filename), local_dir)
|
|
748
|
-
files.append(rel_path)
|
|
749
|
-
except (OSError, IOError):
|
|
750
|
-
pass
|
|
751
|
-
|
|
752
|
-
# Create and save manifest using the new utility function
|
|
752
|
+
if avatar_url:
|
|
753
|
+
old_metadata['avatar_url'] = avatar_url
|
|
754
|
+
except Exception as e:
|
|
755
|
+
# Log the error but continue with manifest creation
|
|
756
|
+
print(f"Warning: Could not fetch avatar URL for {repo_id}: {e}")
|
|
757
|
+
|
|
758
|
+
# CRITICAL: Always create the manifest file, regardless of metadata fetch failures
|
|
759
|
+
try:
|
|
753
760
|
save_manifest_with_files_metadata(repo_id, local_dir, old_metadata)
|
|
754
|
-
|
|
755
|
-
except Exception:
|
|
756
|
-
#
|
|
757
|
-
|
|
761
|
+
print(f"[OK] Successfully created nexa.manifest for {repo_id}")
|
|
762
|
+
except Exception as e:
|
|
763
|
+
# This is critical - if manifest creation fails, we should know about it
|
|
764
|
+
print(f"ERROR: Failed to create nexa.manifest for {repo_id}: {e}")
|
|
765
|
+
# Try a fallback approach - create a minimal manifest
|
|
766
|
+
try:
|
|
767
|
+
minimal_manifest = {
|
|
768
|
+
"Name": repo_id,
|
|
769
|
+
"ModelType": "other",
|
|
770
|
+
"PluginId": "unknown",
|
|
771
|
+
"ModelFile": {},
|
|
772
|
+
"MMProjFile": {"Name": "", "Downloaded": False, "Size": 0},
|
|
773
|
+
"TokenizerFile": {"Name": "", "Downloaded": False, "Size": 0},
|
|
774
|
+
"ExtraFiles": None,
|
|
775
|
+
"pipeline_tag": old_metadata.get('pipeline_tag'),
|
|
776
|
+
"download_time": old_metadata.get('download_time'),
|
|
777
|
+
"avatar_url": old_metadata.get('avatar_url')
|
|
778
|
+
}
|
|
779
|
+
save_download_metadata(local_dir, minimal_manifest)
|
|
780
|
+
print(f"[OK] Created minimal nexa.manifest for {repo_id} as fallback")
|
|
781
|
+
except Exception as fallback_error:
|
|
782
|
+
print(f"CRITICAL ERROR: Could not create even minimal manifest for {repo_id}: {fallback_error}")
|
|
758
783
|
|
|
759
784
|
def _download_single_file(
|
|
760
785
|
self,
|
|
@@ -771,7 +796,7 @@ class HuggingFaceDownloader:
|
|
|
771
796
|
# Check if file already exists
|
|
772
797
|
local_file_path = os.path.join(file_local_dir, file_name)
|
|
773
798
|
if not force_download and self._check_file_exists_and_valid(local_file_path):
|
|
774
|
-
print(f"
|
|
799
|
+
print(f"[SKIP] File already exists: {file_name}")
|
|
775
800
|
# Stop progress tracking
|
|
776
801
|
if progress_tracker:
|
|
777
802
|
progress_tracker.stop_tracking()
|
|
@@ -878,7 +903,7 @@ class HuggingFaceDownloader:
|
|
|
878
903
|
# Check if file already exists
|
|
879
904
|
local_file_path = os.path.join(repo_local_dir, file_name)
|
|
880
905
|
if not force_download and self._check_file_exists_and_valid(local_file_path):
|
|
881
|
-
print(f"
|
|
906
|
+
print(f"[SKIP] File already exists: {file_name}")
|
|
882
907
|
overall_progress.update(1)
|
|
883
908
|
continue
|
|
884
909
|
|
nexaai/utils/progress_tracker.py
CHANGED
|
@@ -249,11 +249,11 @@ class DownloadProgressTracker:
|
|
|
249
249
|
if known_total and total_size_raw > 0:
|
|
250
250
|
# Known total size - show actual progress
|
|
251
251
|
filled_width = int(bar_width * min(percentage, 100) / 100)
|
|
252
|
-
bar = '
|
|
252
|
+
bar = '#' * filled_width + '-' * (bar_width - filled_width)
|
|
253
253
|
else:
|
|
254
254
|
# Unknown total size - show animated progress
|
|
255
255
|
animation_pos = int(time.time() * 2) % bar_width
|
|
256
|
-
bar = '
|
|
256
|
+
bar = '-' * animation_pos + '#' + '-' * (bar_width - animation_pos - 1)
|
|
257
257
|
|
|
258
258
|
# Format the progress line
|
|
259
259
|
status = progress_data.get('status', 'unknown')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
nexaai/__init__.py,sha256=jXdC4vv6DBK1fVewYTYSUhOOYfvf_Mk81UIeMGGIKUg,2029
|
|
2
|
-
nexaai/_stub.cpython-310-darwin.so,sha256=
|
|
3
|
-
nexaai/_version.py,sha256=
|
|
2
|
+
nexaai/_stub.cpython-310-darwin.so,sha256=9KOKNrUGVqL6gpYTZeoe8K4m23ql2idLS7bOAKZx66I,49832
|
|
3
|
+
nexaai/_version.py,sha256=T1DO6ly5D00OtaJx-g2tJVICeli3sPCEYyayWA7ZY0M,138
|
|
4
4
|
nexaai/asr.py,sha256=NljMXDErwPNMOPaRkJZMEDka9Nk8xyur7L8i924TStY,2054
|
|
5
5
|
nexaai/base.py,sha256=N8PRgDFA-XPku2vWnQIofQ7ipz3pPlO6f8YZGnuhquE,982
|
|
6
6
|
nexaai/common.py,sha256=yBnIbqYaQYnfrl7IczOBh6MDibYZVxwaRJEglYcKgGs,3422
|
|
@@ -19,7 +19,7 @@ nexaai/binds/__init__.py,sha256=T9Ua7SzHNglSeEqXlfH5ymYXRyXhNKkC9z_y_bWCNMo,80
|
|
|
19
19
|
nexaai/binds/common_bind.cpython-310-darwin.so,sha256=FF5WuJj0fNCim_HjseBQu38vL-1M5zI_7EVTD7Bs-Bc,233960
|
|
20
20
|
nexaai/binds/embedder_bind.cpython-310-darwin.so,sha256=mU6hP0SyH8vcmPpC2GIr7ioK7539dsg_YbmrBdmj7l0,202032
|
|
21
21
|
nexaai/binds/libcrypto.dylib,sha256=ysW8ydmDPnnNRy3AHESjJwMTFfmGDKU9eLIaiR37ca0,5091432
|
|
22
|
-
nexaai/binds/libnexa_bridge.dylib,sha256=
|
|
22
|
+
nexaai/binds/libnexa_bridge.dylib,sha256=Lj_c15pShhyMurrFd6k2YegjfqWH995cOnk1zRHTbhY,250712
|
|
23
23
|
nexaai/binds/libssl.dylib,sha256=JHPTSbRFnImmoWDO9rFdiKb0lJMT3q78VEsx-5-S0sk,889520
|
|
24
24
|
nexaai/binds/llm_bind.cpython-310-darwin.so,sha256=aYqMs5VhC07RNZZgyS9JeYJJgWCl-toZOmt6vXu5yp0,183008
|
|
25
25
|
nexaai/binds/nexa_llama_cpp/libggml-base.dylib,sha256=oikz7Qxzx6A0mPROq7uHTUwWn66LvvOjcdVstG-M8Fw,629528
|
|
@@ -359,14 +359,14 @@ nexaai/tts_impl/pybind_tts_impl.py,sha256=mpn44r6pfYLIl-NrEy2dXHjGtWtNCmM7HRyxiA
|
|
|
359
359
|
nexaai/utils/avatar_fetcher.py,sha256=bWy8ujgbOiTHFCjFxTwkn3uXbZ84PgEGUkXkR3MH4bI,3821
|
|
360
360
|
nexaai/utils/decode.py,sha256=61n4Zf6c5QLyqGoctEitlI9BX3tPlP2a5aaKNHbw3T4,404
|
|
361
361
|
nexaai/utils/manifest_utils.py,sha256=2waOuQErodNHhoAETQqlQgXdVes-T5A4HMb8pUIN9hg,9765
|
|
362
|
-
nexaai/utils/model_manager.py,sha256=
|
|
362
|
+
nexaai/utils/model_manager.py,sha256=YozzHQNa_vfn99WxD1GteGk2L-5Ac2RAIrWTFHzM9yM,50192
|
|
363
363
|
nexaai/utils/model_types.py,sha256=-DER8L4lAUR_iLS99F0r57avwqWtuN21ug5pX2p24_E,1369
|
|
364
|
-
nexaai/utils/progress_tracker.py,sha256=
|
|
364
|
+
nexaai/utils/progress_tracker.py,sha256=jdUqtmPqyhwC9uSKvQcJEYETwSt-OhP4oitdJ94614o,15394
|
|
365
365
|
nexaai/utils/quantization_utils.py,sha256=4gvp6UQfSO9G1FYBwnFtQspTzH9sDbi1PBXw2t1N69M,7650
|
|
366
366
|
nexaai/vlm_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
367
367
|
nexaai/vlm_impl/mlx_vlm_impl.py,sha256=od1R1mRoIgPG3NHC7JiDlcB_YJY8aklX8Em3ZkeHNpE,10734
|
|
368
368
|
nexaai/vlm_impl/pybind_vlm_impl.py,sha256=5ZMFgDATthmMzjrd-vE5KX5ZAMoWPYbF_FTLz8DBKIk,8908
|
|
369
|
-
nexaai-1.0.
|
|
370
|
-
nexaai-1.0.
|
|
371
|
-
nexaai-1.0.
|
|
372
|
-
nexaai-1.0.
|
|
369
|
+
nexaai-1.0.8.dist-info/METADATA,sha256=GyMk3Sv3FIByGbG2GE_rK3imhyZ4L9_R3tB6FWwCOYY,1197
|
|
370
|
+
nexaai-1.0.8.dist-info/WHEEL,sha256=0KYp5feZ1CMUhsfFXKpSQTbSmQbXy4mv6yPPVBXg2EM,110
|
|
371
|
+
nexaai-1.0.8.dist-info/top_level.txt,sha256=LRE2YERlrZk2vfuygnSzsEeqSknnZbz3Z1MHyNmBU4w,7
|
|
372
|
+
nexaai-1.0.8.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|