nexaai 1.0.13rc1__cp310-cp310-macosx_13_0_x86_64.whl → 1.0.13rc2__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.

Binary file
nexaai/_version.py CHANGED
@@ -1,4 +1,4 @@
1
1
  # This file is generated by CMake from _version.py.in
2
2
  # Do not modify this file manually - it will be overwritten
3
3
 
4
- __version__ = "1.0.13-rc1"
4
+ __version__ = "1.0.13-rc2"
Binary file
@@ -11,7 +11,7 @@ This module provides utilities to:
11
11
  import os
12
12
  import json
13
13
  from datetime import datetime
14
- from typing import Dict, Any, List, Optional
14
+ from typing import Dict, Any, List, Optional, Union
15
15
 
16
16
  from .quantization_utils import (
17
17
  extract_quantization_from_filename,
@@ -101,7 +101,7 @@ def save_download_metadata(directory_path: str, metadata: Dict[str, Any]) -> Non
101
101
  pass
102
102
 
103
103
 
104
- def create_gguf_manifest(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any]) -> Dict[str, Any]:
104
+ def create_gguf_manifest(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None) -> Dict[str, Any]:
105
105
  """Create GGUF format manifest."""
106
106
 
107
107
  # Load existing manifest to merge GGUF files if it exists
@@ -111,14 +111,27 @@ def create_gguf_manifest(repo_id: str, files: List[str], directory_path: str, ol
111
111
  if existing_manifest and "ModelFile" in existing_manifest:
112
112
  model_files = existing_manifest["ModelFile"].copy()
113
113
 
114
+ # Initialize MMProjFile from existing manifest or empty
115
+ mmproj_file = {
116
+ "Name": "",
117
+ "Downloaded": False,
118
+ "Size": 0
119
+ }
120
+ if existing_manifest and "MMProjFile" in existing_manifest:
121
+ mmproj_file = existing_manifest["MMProjFile"].copy()
122
+
114
123
  # Process GGUF files
115
- for file_name in files:
116
- if file_name.endswith('.gguf'):
117
- # Use the new enum-based quantization extraction
118
- quantization_type = extract_quantization_from_filename(file_name)
119
- quant_level = quantization_type.value if quantization_type else "UNKNOWN"
124
+ for current_file_name in files:
125
+ if current_file_name.endswith('.gguf'):
126
+ # Check if this file is an mmproj file
127
+ is_current_mmproj = 'mmproj' in current_file_name.lower()
128
+
129
+ # If we're downloading specific files and this is marked as mmproj, respect that
130
+ if is_mmproj and file_name is not None:
131
+ filenames_to_check = file_name if isinstance(file_name, list) else [file_name]
132
+ is_current_mmproj = current_file_name in filenames_to_check
120
133
 
121
- file_path = os.path.join(directory_path, file_name)
134
+ file_path = os.path.join(directory_path, current_file_name)
122
135
  file_size = 0
123
136
  if os.path.exists(file_path):
124
137
  try:
@@ -126,22 +139,31 @@ def create_gguf_manifest(repo_id: str, files: List[str], directory_path: str, ol
126
139
  except (OSError, IOError):
127
140
  pass
128
141
 
129
- model_files[quant_level] = {
130
- "Name": file_name,
131
- "Downloaded": True,
132
- "Size": file_size
133
- }
142
+ if is_current_mmproj:
143
+ # This is an mmproj file, put it in MMProjFile
144
+ mmproj_file = {
145
+ "Name": current_file_name,
146
+ "Downloaded": True,
147
+ "Size": file_size
148
+ }
149
+ else:
150
+ # Regular model file, put in ModelFile
151
+ # Use the new enum-based quantization extraction
152
+ quantization_type = extract_quantization_from_filename(current_file_name)
153
+ quant_level = quantization_type.value if quantization_type else "UNKNOWN"
154
+
155
+ model_files[quant_level] = {
156
+ "Name": current_file_name,
157
+ "Downloaded": True,
158
+ "Size": file_size
159
+ }
134
160
 
135
161
  manifest = {
136
162
  "Name": repo_id,
137
163
  "ModelType": PIPELINE_TO_MODEL_TYPE.get(old_metadata.get('pipeline_tag'), "other"),
138
164
  "PluginId": "llama_cpp",
139
165
  "ModelFile": model_files,
140
- "MMProjFile": {
141
- "Name": "",
142
- "Downloaded": False,
143
- "Size": 0
144
- },
166
+ "MMProjFile": mmproj_file,
145
167
  "TokenizerFile": {
146
168
  "Name": "",
147
169
  "Downloaded": False,
@@ -157,20 +179,27 @@ def create_gguf_manifest(repo_id: str, files: List[str], directory_path: str, ol
157
179
  return manifest
158
180
 
159
181
 
160
- def create_mlx_manifest(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any]) -> Dict[str, Any]:
182
+ def create_mlx_manifest(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None) -> Dict[str, Any]:
161
183
  """Create MLX format manifest."""
162
184
 
163
185
  model_files = {}
164
186
  extra_files = []
165
187
 
188
+ # Initialize MMProjFile
189
+ mmproj_file = {
190
+ "Name": "",
191
+ "Downloaded": False,
192
+ "Size": 0
193
+ }
194
+
166
195
  # Try different methods to extract quantization for MLX models
167
196
  quantization_type = detect_quantization_for_mlx(repo_id, directory_path)
168
197
 
169
198
  # Use the detected quantization or default to "DEFAULT"
170
199
  quant_level = quantization_type.value if quantization_type else "DEFAULT"
171
200
 
172
- for file_name in files:
173
- file_path = os.path.join(directory_path, file_name)
201
+ for current_file_name in files:
202
+ file_path = os.path.join(directory_path, current_file_name)
174
203
  file_size = 0
175
204
  if os.path.exists(file_path):
176
205
  try:
@@ -178,17 +207,32 @@ def create_mlx_manifest(repo_id: str, files: List[str], directory_path: str, old
178
207
  except (OSError, IOError):
179
208
  pass
180
209
 
210
+ # Check if this file is an mmproj file
211
+ is_current_mmproj = 'mmproj' in current_file_name.lower()
212
+
213
+ # If we're downloading specific files and this is marked as mmproj, respect that
214
+ if is_mmproj and file_name is not None:
215
+ filenames_to_check = file_name if isinstance(file_name, list) else [file_name]
216
+ is_current_mmproj = current_file_name in filenames_to_check
217
+
218
+ if is_current_mmproj:
219
+ # This is an mmproj file, put it in MMProjFile
220
+ mmproj_file = {
221
+ "Name": current_file_name,
222
+ "Downloaded": True,
223
+ "Size": file_size
224
+ }
181
225
  # Check if this is a main model file (safetensors but not index files)
182
- if (file_name.endswith('.safetensors') and not file_name.endswith('.index.json')):
226
+ elif (current_file_name.endswith('.safetensors') and not current_file_name.endswith('.index.json')):
183
227
  model_files[quant_level] = {
184
- "Name": file_name,
228
+ "Name": current_file_name,
185
229
  "Downloaded": True,
186
230
  "Size": file_size
187
231
  }
188
232
  else:
189
233
  # Add to extra files
190
234
  extra_files.append({
191
- "Name": file_name,
235
+ "Name": current_file_name,
192
236
  "Downloaded": True,
193
237
  "Size": file_size
194
238
  })
@@ -198,11 +242,7 @@ def create_mlx_manifest(repo_id: str, files: List[str], directory_path: str, old
198
242
  "ModelType": PIPELINE_TO_MODEL_TYPE.get(old_metadata.get('pipeline_tag'), "other"),
199
243
  "PluginId": "mlx",
200
244
  "ModelFile": model_files,
201
- "MMProjFile": {
202
- "Name": "",
203
- "Downloaded": False,
204
- "Size": 0
205
- },
245
+ "MMProjFile": mmproj_file,
206
246
  "TokenizerFile": {
207
247
  "Name": "",
208
248
  "Downloaded": False,
@@ -232,7 +272,7 @@ def detect_model_type(files: List[str]) -> str:
232
272
  return "mlx"
233
273
 
234
274
 
235
- def create_manifest_from_files(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any]) -> Dict[str, Any]:
275
+ def create_manifest_from_files(repo_id: str, files: List[str], directory_path: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None) -> Dict[str, Any]:
236
276
  """
237
277
  Create appropriate manifest format based on detected model type.
238
278
 
@@ -241,6 +281,8 @@ def create_manifest_from_files(repo_id: str, files: List[str], directory_path: s
241
281
  files: List of files in the model directory
242
282
  directory_path: Path to the model directory
243
283
  old_metadata: Existing metadata (pipeline_tag, download_time, avatar_url)
284
+ is_mmproj: Whether the downloaded file is an mmproj file
285
+ file_name: The specific file(s) that were downloaded (None if entire repo was downloaded)
244
286
 
245
287
  Returns:
246
288
  Dict containing the appropriate manifest format
@@ -248,12 +290,12 @@ def create_manifest_from_files(repo_id: str, files: List[str], directory_path: s
248
290
  model_type = detect_model_type(files)
249
291
 
250
292
  if model_type == "gguf":
251
- return create_gguf_manifest(repo_id, files, directory_path, old_metadata)
293
+ return create_gguf_manifest(repo_id, files, directory_path, old_metadata, is_mmproj, file_name)
252
294
  else: # mlx or other
253
- return create_mlx_manifest(repo_id, files, directory_path, old_metadata)
295
+ return create_mlx_manifest(repo_id, files, directory_path, old_metadata, is_mmproj, file_name)
254
296
 
255
297
 
256
- def save_manifest_with_files_metadata(repo_id: str, local_dir: str, old_metadata: Dict[str, Any]) -> None:
298
+ def save_manifest_with_files_metadata(repo_id: str, local_dir: str, old_metadata: Dict[str, Any], is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None) -> None:
257
299
  """
258
300
  Create and save manifest based on files found in the directory.
259
301
 
@@ -261,6 +303,8 @@ def save_manifest_with_files_metadata(repo_id: str, local_dir: str, old_metadata
261
303
  repo_id: Repository ID
262
304
  local_dir: Local directory containing the model files
263
305
  old_metadata: Existing metadata to preserve
306
+ is_mmproj: Whether the downloaded file is an mmproj file
307
+ file_name: The specific file(s) that were downloaded (None if entire repo was downloaded)
264
308
  """
265
309
  # Get list of files in the directory
266
310
  files = []
@@ -274,7 +318,7 @@ def save_manifest_with_files_metadata(repo_id: str, local_dir: str, old_metadata
274
318
  pass
275
319
 
276
320
  # Create appropriate manifest
277
- manifest = create_manifest_from_files(repo_id, files, local_dir, old_metadata)
321
+ manifest = create_manifest_from_files(repo_id, files, local_dir, old_metadata, is_mmproj, file_name)
278
322
 
279
323
  # Save manifest
280
324
  save_download_metadata(local_dir, manifest)
@@ -21,6 +21,13 @@ from .manifest_utils import (
21
21
  # Default path for model storage
22
22
  DEFAULT_MODEL_SAVING_PATH = "~/.cache/nexa.ai/nexa_sdk/models/"
23
23
 
24
+
25
+ @dataclass
26
+ class MMProjInfo:
27
+ """Data class for mmproj file information."""
28
+ mmproj_path: Optional[str] = None
29
+ size: int = 0
30
+
24
31
  @dataclass
25
32
  class DownloadedModel:
26
33
  """Data class representing a downloaded model with all its metadata."""
@@ -34,6 +41,7 @@ class DownloadedModel:
34
41
  pipeline_tag: Optional[str] = None # Pipeline tag from HuggingFace model info
35
42
  download_time: Optional[str] = None # ISO format timestamp of download
36
43
  avatar_url: Optional[str] = None # Avatar URL for the model author
44
+ mmproj_info: Optional[MMProjInfo] = None # mmproj file information
37
45
 
38
46
  def to_dict(self) -> Dict[str, Any]:
39
47
  """Convert to dictionary format for backward compatibility."""
@@ -47,7 +55,11 @@ class DownloadedModel:
47
55
  'full_repo_download_complete': self.full_repo_download_complete,
48
56
  'pipeline_tag': self.pipeline_tag,
49
57
  'download_time': self.download_time,
50
- 'avatar_url': self.avatar_url
58
+ 'avatar_url': self.avatar_url,
59
+ 'mmproj_info': {
60
+ 'mmproj_path': self.mmproj_info.mmproj_path,
61
+ 'size': self.mmproj_info.size
62
+ } if self.mmproj_info else None
51
63
  }
52
64
  return result
53
65
 
@@ -125,6 +137,46 @@ def _has_valid_metadata(directory_path: str) -> bool:
125
137
  return os.path.exists(manifest_path) or os.path.exists(old_metadata_path)
126
138
 
127
139
 
140
+ def _extract_mmproj_info(manifest: Dict[str, Any], local_path: str) -> Optional[MMProjInfo]:
141
+ """
142
+ Extract mmproj information from manifest data.
143
+
144
+ Args:
145
+ manifest: Dictionary containing manifest data
146
+ local_path: Local path to the model directory
147
+
148
+ Returns:
149
+ MMProjInfo object if mmproj file exists, None otherwise
150
+ """
151
+ # Check if manifest has MMProjFile information
152
+ mmproj_file_info = manifest.get('MMProjFile')
153
+ if not mmproj_file_info or not mmproj_file_info.get('Downloaded') or not mmproj_file_info.get('Name'):
154
+ return None
155
+
156
+ mmproj_filename = mmproj_file_info.get('Name', '')
157
+ if not mmproj_filename:
158
+ return None
159
+
160
+ # Construct full path to mmproj file
161
+ mmproj_path = os.path.join(local_path, mmproj_filename)
162
+
163
+ # Get size from manifest, but verify file exists
164
+ mmproj_size = mmproj_file_info.get('Size', 0)
165
+ if os.path.exists(mmproj_path):
166
+ try:
167
+ # Verify size matches actual file size
168
+ actual_size = os.path.getsize(mmproj_path)
169
+ mmproj_size = actual_size # Use actual size if different
170
+ except (OSError, IOError):
171
+ # If we can't get actual size, use size from manifest
172
+ pass
173
+ else:
174
+ # File doesn't exist, don't include mmproj info
175
+ return None
176
+
177
+ return MMProjInfo(mmproj_path=mmproj_path, size=mmproj_size)
178
+
179
+
128
180
  def _scan_for_repo_folders(base_path: str) -> List[DownloadedModel]:
129
181
  """Scan a directory for repository folders and return model information."""
130
182
  models = []
@@ -159,6 +211,10 @@ def _scan_for_repo_folders(base_path: str) -> List[DownloadedModel]:
159
211
  # Load metadata if it exists
160
212
  repo_id = f"{item}/{subitem}"
161
213
  metadata = load_download_metadata(subitem_path, repo_id)
214
+
215
+ # Extract mmproj information
216
+ mmproj_info = _extract_mmproj_info(metadata, subitem_path)
217
+
162
218
  models.append(DownloadedModel(
163
219
  repo_id=repo_id,
164
220
  files=files,
@@ -169,7 +225,8 @@ def _scan_for_repo_folders(base_path: str) -> List[DownloadedModel]:
169
225
  full_repo_download_complete=download_complete,
170
226
  pipeline_tag=metadata.get('pipeline_tag'),
171
227
  download_time=metadata.get('download_time'),
172
- avatar_url=metadata.get('avatar_url')
228
+ avatar_url=metadata.get('avatar_url'),
229
+ mmproj_info=mmproj_info
173
230
  ))
174
231
  else:
175
232
  direct_files.append(subitem)
@@ -188,6 +245,10 @@ def _scan_for_repo_folders(base_path: str) -> List[DownloadedModel]:
188
245
  # Load metadata if it exists
189
246
  repo_id = item
190
247
  metadata = load_download_metadata(item_path, repo_id)
248
+
249
+ # Extract mmproj information
250
+ mmproj_info = _extract_mmproj_info(metadata, item_path)
251
+
191
252
  models.append(DownloadedModel(
192
253
  repo_id=repo_id,
193
254
  files=files,
@@ -198,7 +259,8 @@ def _scan_for_repo_folders(base_path: str) -> List[DownloadedModel]:
198
259
  full_repo_download_complete=download_complete,
199
260
  pipeline_tag=metadata.get('pipeline_tag'),
200
261
  download_time=metadata.get('download_time'),
201
- avatar_url=metadata.get('avatar_url')
262
+ avatar_url=metadata.get('avatar_url'),
263
+ mmproj_info=mmproj_info
202
264
  ))
203
265
 
204
266
  except (OSError, IOError):
@@ -236,6 +298,7 @@ def list_downloaded_models(local_dir: Optional[str] = None) -> List[DownloadedMo
236
298
  - pipeline_tag: Optional[str] - Pipeline tag from HuggingFace model info
237
299
  - download_time: Optional[str] - ISO format timestamp when the model was downloaded
238
300
  - avatar_url: Optional[str] - Avatar URL for the model author
301
+ - mmproj_info: Optional[MMProjInfo] - mmproj file information with mmproj_path and size
239
302
  """
240
303
 
241
304
  # Set up local directory
@@ -727,7 +790,7 @@ class HuggingFaceDownloader:
727
790
  # If no expected size, just check that file is not empty
728
791
  return os.path.getsize(file_path) > 0
729
792
 
730
- def _fetch_and_save_metadata(self, repo_id: str, local_dir: str) -> None:
793
+ def _fetch_and_save_metadata(self, repo_id: str, local_dir: str, is_mmproj: bool = False, file_name: Optional[Union[str, List[str]]] = None) -> None:
731
794
  """Fetch model info and save metadata after successful download."""
732
795
  # Initialize metadata with defaults to ensure manifest is always created
733
796
  old_metadata = {
@@ -757,7 +820,7 @@ class HuggingFaceDownloader:
757
820
 
758
821
  # CRITICAL: Always create the manifest file, regardless of metadata fetch failures
759
822
  try:
760
- save_manifest_with_files_metadata(repo_id, local_dir, old_metadata)
823
+ save_manifest_with_files_metadata(repo_id, local_dir, old_metadata, is_mmproj, file_name)
761
824
  print(f"[OK] Successfully created nexa.manifest for {repo_id}")
762
825
  except Exception as e:
763
826
  # This is critical - if manifest creation fails, we should know about it
@@ -819,7 +882,7 @@ class HuggingFaceDownloader:
819
882
  progress_tracker.stop_tracking()
820
883
 
821
884
  # Save metadata after successful download
822
- self._fetch_and_save_metadata(repo_id, file_local_dir)
885
+ self._fetch_and_save_metadata(repo_id, file_local_dir, self._current_is_mmproj, self._current_file_name)
823
886
 
824
887
  return downloaded_path
825
888
 
@@ -864,7 +927,7 @@ class HuggingFaceDownloader:
864
927
  progress_tracker.stop_tracking()
865
928
 
866
929
  # Save metadata after successful download
867
- self._fetch_and_save_metadata(repo_id, repo_local_dir)
930
+ self._fetch_and_save_metadata(repo_id, repo_local_dir, self._current_is_mmproj, self._current_file_name)
868
931
 
869
932
  return downloaded_path
870
933
 
@@ -926,7 +989,7 @@ class HuggingFaceDownloader:
926
989
  progress_tracker.stop_tracking()
927
990
 
928
991
  # Save metadata after successful download
929
- self._fetch_and_save_metadata(repo_id, repo_local_dir)
992
+ self._fetch_and_save_metadata(repo_id, repo_local_dir, self._current_is_mmproj, self._current_file_name)
930
993
 
931
994
  return repo_local_dir
932
995
 
@@ -951,7 +1014,8 @@ class HuggingFaceDownloader:
951
1014
  local_dir: Optional[str] = None,
952
1015
  progress_callback: Optional[Callable[[Dict[str, Any]], None]] = None,
953
1016
  show_progress: bool = True,
954
- force_download: bool = False
1017
+ force_download: bool = False,
1018
+ is_mmproj: bool = False
955
1019
  ) -> str:
956
1020
  """
957
1021
  Main download method that handles all download scenarios.
@@ -970,6 +1034,10 @@ class HuggingFaceDownloader:
970
1034
  # Validate and normalize parameters
971
1035
  repo_id, file_name = self._validate_and_setup_params(repo_id, file_name)
972
1036
 
1037
+ # Store parameters as instance variables for use in _fetch_and_save_metadata
1038
+ self._current_is_mmproj = is_mmproj
1039
+ self._current_file_name = file_name
1040
+
973
1041
  # Set up local directory
974
1042
  local_dir = self._created_dir_if_not_exists(local_dir)
975
1043
 
@@ -1038,7 +1106,8 @@ def download_from_huggingface(
1038
1106
  show_progress: bool = True,
1039
1107
  token: Union[bool, str, None] = None,
1040
1108
  custom_endpoint: Optional[str] = None,
1041
- force_download: bool = False
1109
+ force_download: bool = False,
1110
+ is_mmproj: Optional[bool] = None
1042
1111
  ) -> str:
1043
1112
  """
1044
1113
  Download models or files from HuggingFace Hub or custom mirror endpoints.
@@ -1065,6 +1134,9 @@ def download_from_huggingface(
1065
1134
  The endpoint will be used to initialize HfApi for all downloads.
1066
1135
  force_download (bool, optional): If True, download files even if they already exist locally.
1067
1136
  Default False (skip existing files).
1137
+ is_mmproj (bool, optional): Whether the file being downloaded is an mmproj file. Only used when
1138
+ file_name is not None. If None, defaults to True if 'mmproj' is in
1139
+ the filename, False otherwise.
1068
1140
 
1069
1141
  Returns:
1070
1142
  str: Path to the downloaded file or directory
@@ -1101,6 +1173,15 @@ def download_from_huggingface(
1101
1173
  }
1102
1174
  }
1103
1175
  """
1176
+ # Set default value for is_mmproj based on filename if not explicitly provided
1177
+ if is_mmproj is None and file_name is not None:
1178
+ # Check if any filename contains 'mmproj'
1179
+ filenames_to_check = file_name if isinstance(file_name, list) else [file_name]
1180
+ is_mmproj = any('mmproj' in filename.lower() for filename in filenames_to_check)
1181
+ elif is_mmproj is None:
1182
+ # Default to False if no file_name is provided
1183
+ is_mmproj = False
1184
+
1104
1185
  # Create downloader instance with custom endpoint if provided
1105
1186
  downloader = HuggingFaceDownloader(
1106
1187
  endpoint=custom_endpoint,
@@ -1115,7 +1196,8 @@ def download_from_huggingface(
1115
1196
  local_dir=local_dir,
1116
1197
  progress_callback=progress_callback,
1117
1198
  show_progress=show_progress,
1118
- force_download=force_download
1199
+ force_download=force_download,
1200
+ is_mmproj=is_mmproj
1119
1201
  )
1120
1202
 
1121
1203
 
@@ -1128,7 +1210,8 @@ def _download_model_if_needed(
1128
1210
  model_path: str,
1129
1211
  param_name: str,
1130
1212
  progress_callback: Optional[Callable[[Dict[str, Any]], None]] = None,
1131
- token: Union[bool, str, None] = None
1213
+ token: Union[bool, str, None] = None,
1214
+ is_mmproj: bool = False
1132
1215
  ) -> str:
1133
1216
  """
1134
1217
  Helper function to download a model from HuggingFace if it doesn't exist locally.
@@ -1163,7 +1246,8 @@ def _download_model_if_needed(
1163
1246
  enable_transfer=True,
1164
1247
  progress_callback=progress_callback,
1165
1248
  show_progress=True,
1166
- token=token
1249
+ token=token,
1250
+ is_mmproj=is_mmproj
1167
1251
  )
1168
1252
 
1169
1253
  return downloaded_path
@@ -1254,7 +1338,7 @@ def auto_download_model(func: Callable) -> Callable:
1254
1338
  if mmproj_path is not None:
1255
1339
  try:
1256
1340
  downloaded_mmproj_path = _download_model_if_needed(
1257
- mmproj_path, 'mmproj_path', progress_callback, token
1341
+ mmproj_path, 'mmproj_path', progress_callback, token, is_mmproj=True
1258
1342
  )
1259
1343
 
1260
1344
  # Replace mmproj_path with downloaded path
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nexaai
3
- Version: 1.0.13rc1
3
+ Version: 1.0.13rc2
4
4
  Summary: Python bindings for NexaSDK C-lib backend
5
5
  Author-email: "Nexa AI, Inc." <dev@nexa.ai>
6
6
  Project-URL: Homepage, https://github.com/NexaAI/nexasdk-bridge
@@ -1,6 +1,6 @@
1
1
  nexaai/__init__.py,sha256=jXdC4vv6DBK1fVewYTYSUhOOYfvf_Mk81UIeMGGIKUg,2029
2
- nexaai/_stub.cpython-310-darwin.so,sha256=R8fF_ouYUW419bQTnDSU8pu9M2bskkgYjx2DFG5qSsQ,49832
3
- nexaai/_version.py,sha256=akSnDABX0T874oWowjXB3MrX7aTHCZHWA6-X80hJ7bY,143
2
+ nexaai/_stub.cpython-310-darwin.so,sha256=6Rm0bf_EO8r2MetZDjJ7E65gIcteq6ZDkPSLYh2NJj4,49832
3
+ nexaai/_version.py,sha256=phWIqzyUJzHhqe_9HXfqatPXqoSNklwhM8R24HQckh8,143
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
@@ -18,9 +18,7 @@ nexaai/asr_impl/pybind_asr_impl.py,sha256=pE9Hb_hMi5yAc4MF83bLVOb8zDtreCkB3_u7XE
18
18
  nexaai/binds/__init__.py,sha256=eYuay_8DDXeOUWz2_R9HFSabohxs6hvZn391t2L0Po0,104
19
19
  nexaai/binds/common_bind.cpython-310-darwin.so,sha256=7xH5yNkK6Ot-2f9vxmultr9NIeTemlmN5tHIYp8SZHs,233960
20
20
  nexaai/binds/embedder_bind.cpython-310-darwin.so,sha256=eQwf9m58Yrl_ZZzWlstBHfHD-s3UMFi0JNPty-Pc524,202032
21
- nexaai/binds/libcrypto.dylib,sha256=ysW8ydmDPnnNRy3AHESjJwMTFfmGDKU9eLIaiR37ca0,5091432
22
- nexaai/binds/libnexa_bridge.dylib,sha256=fAc-fbOkwd_5rPLHJ-c01dEG5YeFjM25iqRslIIeBIw,250592
23
- nexaai/binds/libssl.dylib,sha256=JHPTSbRFnImmoWDO9rFdiKb0lJMT3q78VEsx-5-S0sk,889520
21
+ nexaai/binds/libnexa_bridge.dylib,sha256=uJ6vhHoU5Q-QE8jC2PHPqVGAKhgUig_GWZ-HODXrYqs,250376
24
22
  nexaai/binds/llm_bind.cpython-310-darwin.so,sha256=08DuSv91LIVCS5BSfSx3Nuz088h62lm3MV2yDTSIKt4,183008
25
23
  nexaai/binds/vlm_bind.cpython-310-darwin.so,sha256=x1hxuCx09P69swsVj46FXHKUH5Ln39ISBjBscyJWESM,183000
26
24
  nexaai/binds/nexa_llama_cpp/libggml-base.dylib,sha256=GyOkHOM-5uHp7NUZ4Sr9BWak6BYpcc9aqI9A-zPnQp4,629528
@@ -29,7 +27,7 @@ nexaai/binds/nexa_llama_cpp/libggml-metal.so,sha256=Xhhl_tLg1xmCIQVrKjqPFaLHAlx_
29
27
  nexaai/binds/nexa_llama_cpp/libggml.dylib,sha256=12Q1Z98oM81hxzT_GMQsW5rlhC8DOMsX6luWVCFQHcI,58336
30
28
  nexaai/binds/nexa_llama_cpp/libllama.dylib,sha256=ORoTILXdGGX6MLMh-IWLIp4P5UEPOjE4lvWOKM18pCk,1982280
31
29
  nexaai/binds/nexa_llama_cpp/libmtmd.dylib,sha256=1plWvthTQf8IXbXthMG0MZXzWhbzV6ghdVzVFIb1FnU,701504
32
- nexaai/binds/nexa_llama_cpp/libnexa_plugin.dylib,sha256=zp1dcbAp9XcrIk3mUR346LAqCxzQLfSnC56pszl6jgQ,2644752
30
+ nexaai/binds/nexa_llama_cpp/libnexa_plugin.dylib,sha256=3Dpj5aDJUcJ0CGyl7hstBBsorDwM3U0vVsCjmDB34dg,2025496
33
31
  nexaai/cv_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
32
  nexaai/cv_impl/mlx_cv_impl.py,sha256=gKECQOv8iaWwG3bl7xeqVy2NN_9K7tYerIFzfn4eLo4,3228
35
33
  nexaai/cv_impl/pybind_cv_impl.py,sha256=uSmwBste4cT7c8DQmXzRLmzwDf773PAbXNYWW1UzVls,1064
@@ -359,15 +357,15 @@ nexaai/tts_impl/mlx_tts_impl.py,sha256=i_uNPdvlXYtL3e01oKjDlP9jgkWCRt1bBHsExaaiJ
359
357
  nexaai/tts_impl/pybind_tts_impl.py,sha256=mpn44r6pfYLIl-NrEy2dXHjGtWtNCmM7HRyxiANxUI4,1444
360
358
  nexaai/utils/avatar_fetcher.py,sha256=bWy8ujgbOiTHFCjFxTwkn3uXbZ84PgEGUkXkR3MH4bI,3821
361
359
  nexaai/utils/decode.py,sha256=61n4Zf6c5QLyqGoctEitlI9BX3tPlP2a5aaKNHbw3T4,404
362
- nexaai/utils/manifest_utils.py,sha256=2waOuQErodNHhoAETQqlQgXdVes-T5A4HMb8pUIN9hg,9765
363
- nexaai/utils/model_manager.py,sha256=ELmF2gVw7c0f_oGbbx0ldXrmCuJVxTZ9X-xsW59zWks,52300
360
+ nexaai/utils/manifest_utils.py,sha256=sR9Nme4GbD3Cb3fMd55yLvGZpqxb71vd6b2XZTsrIGM,12328
361
+ nexaai/utils/model_manager.py,sha256=p2kJKK63Zk-rEUucFsgY0T5PyXi_IvJY0gKewUVcAV4,56081
364
362
  nexaai/utils/model_types.py,sha256=-DER8L4lAUR_iLS99F0r57avwqWtuN21ug5pX2p24_E,1369
365
363
  nexaai/utils/progress_tracker.py,sha256=jdUqtmPqyhwC9uSKvQcJEYETwSt-OhP4oitdJ94614o,15394
366
364
  nexaai/utils/quantization_utils.py,sha256=4gvp6UQfSO9G1FYBwnFtQspTzH9sDbi1PBXw2t1N69M,7650
367
365
  nexaai/vlm_impl/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
368
366
  nexaai/vlm_impl/mlx_vlm_impl.py,sha256=od1R1mRoIgPG3NHC7JiDlcB_YJY8aklX8Em3ZkeHNpE,10734
369
367
  nexaai/vlm_impl/pybind_vlm_impl.py,sha256=n4lBTeDA9i07Fz1sq4694XkA2XQtnJnR9RaaKK0CrcM,8458
370
- nexaai-1.0.13rc1.dist-info/METADATA,sha256=2ZDKnf6R77BIkVCNLzAdpGXwoXEoY-GL6R3oHUJPcns,1201
371
- nexaai-1.0.13rc1.dist-info/WHEEL,sha256=0KYp5feZ1CMUhsfFXKpSQTbSmQbXy4mv6yPPVBXg2EM,110
372
- nexaai-1.0.13rc1.dist-info/top_level.txt,sha256=LRE2YERlrZk2vfuygnSzsEeqSknnZbz3Z1MHyNmBU4w,7
373
- nexaai-1.0.13rc1.dist-info/RECORD,,
368
+ nexaai-1.0.13rc2.dist-info/METADATA,sha256=QDTSLe7dtUuRQzCK7l0wE49_GoDsm8QN5W_3mPhdlfc,1201
369
+ nexaai-1.0.13rc2.dist-info/WHEEL,sha256=0KYp5feZ1CMUhsfFXKpSQTbSmQbXy4mv6yPPVBXg2EM,110
370
+ nexaai-1.0.13rc2.dist-info/top_level.txt,sha256=LRE2YERlrZk2vfuygnSzsEeqSknnZbz3Z1MHyNmBU4w,7
371
+ nexaai-1.0.13rc2.dist-info/RECORD,,
Binary file
nexaai/binds/libssl.dylib DELETED
Binary file