omnius 1.0.642 → 1.0.643

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.
@@ -618,10 +618,28 @@ function installSystemd(nodeBin, omniusScript, user) {
618
618
 
619
619
  var unitDir = path.join(userHome, ".config", "systemd", "user");
620
620
  var unitPath = path.join(unitDir, SERVICE_LABEL + ".service");
621
+ var envDir = path.join(userHome, ".config", "omnius");
622
+ var envPath = path.join(envDir, "daemon.env");
621
623
  var logDir = path.join(userHome, ".omnius");
622
624
 
623
625
  try { fs.mkdirSync(unitDir, { recursive: true }); } catch (e) {}
626
+ try { fs.mkdirSync(envDir, { recursive: true }); } catch (e) {}
624
627
  try { fs.mkdirSync(logDir, { recursive: true }); } catch (e) {}
628
+ try {
629
+ if (!fs.existsSync(envPath)) {
630
+ fs.writeFileSync(envPath, [
631
+ "# Optional Omnius daemon runtime overrides (KEY=value).",
632
+ "# OMNIUS_AUDIO_PYTHON=/absolute/path/to/jetpack/python",
633
+ "# OMNIUS_HF_TOKEN=hf_setup_only_token",
634
+ "# OMNIUS_PYANNOTE_TERMS_ACCEPTED=1",
635
+ "",
636
+ ].join("\n"), { encoding: "utf8", mode: 0o600 });
637
+ } else {
638
+ try { fs.chmodSync(envPath, 0o600); } catch (e) {}
639
+ }
640
+ } catch (e) {
641
+ warn("Could not create optional daemon environment file: " + (e && e.message));
642
+ }
625
643
 
626
644
  // The unit runs: <node> <omniusScript> serve --daemon --quiet
627
645
  // with OMNIUS_DAEMON=1 so the serve command picks the daemon path.
@@ -639,6 +657,7 @@ function installSystemd(nodeBin, omniusScript, user) {
639
657
  "Environment=OMNIUS_DAEMON=1",
640
658
  "Environment=OMNIUS_PORT=" + PORT,
641
659
  "Environment=NODE_ENV=production",
660
+ "EnvironmentFile=-" + envPath,
642
661
  "ExecStart=" + nodeBin + " " + omniusScript + " serve --daemon --quiet",
643
662
  // Restart=always (was on-failure) — also relaunch on clean exit.
644
663
  // Some upgrade flows trigger process.exit(0) (e.g. /update reload,
@@ -16,6 +16,8 @@ import wave
16
16
 
17
17
  if os.environ.get("HF_HUB_OFFLINE") != "1" or os.environ.get("TRANSFORMERS_OFFLINE") != "1":
18
18
  raise RuntimeError("CLAP worker must be started with offline model access enabled")
19
+ if os.environ.get("PYTHONNOUSERSITE") != "1":
20
+ raise RuntimeError("CLAP worker must run from the isolated managed venv without user-site packages")
19
21
 
20
22
  import numpy as np
21
23
  import torch
@@ -12,6 +12,7 @@ from __future__ import annotations
12
12
  import argparse
13
13
  import json
14
14
  import os
15
+ import subprocess
15
16
  import sys
16
17
  import time
17
18
  import wave
@@ -39,6 +40,33 @@ def validate_live_wav(path: str) -> None:
39
40
  raise ValueError("live diarization accepts retained audio windows greater than 0 and at most 6 seconds")
40
41
 
41
42
 
43
+ def load_pcm16_waveform(path: str):
44
+ """Decode locally without TorchCodec, which has no CPython 3.10/aarch64 wheel."""
45
+ import numpy as np
46
+ import torch
47
+
48
+ try:
49
+ with wave.open(path, "rb") as wav:
50
+ if wav.getcomptype() != "NONE" or wav.getsampwidth() != 2:
51
+ raise ValueError("offline reconciliation requires uncompressed PCM16 WAV")
52
+ channels = wav.getnchannels()
53
+ sample_rate = wav.getframerate()
54
+ frames = wav.readframes(wav.getnframes())
55
+ except Exception as exc:
56
+ raise ValueError(f"offline reconciliation requires readable PCM16 WAV: {exc}") from exc
57
+ if channels < 1 or sample_rate < 1 or not frames:
58
+ raise ValueError("offline reconciliation WAV is empty or invalid")
59
+ samples = np.frombuffer(frames, dtype="<i2")
60
+ if samples.size % channels:
61
+ raise ValueError("offline reconciliation WAV has an incomplete PCM frame")
62
+ waveform = samples.reshape(-1, channels).T.astype(np.float32) / 32768.0
63
+ return {
64
+ "waveform": torch.from_numpy(waveform),
65
+ "sample_rate": sample_rate,
66
+ "uri": Path(path).stem,
67
+ }
68
+
69
+
42
70
  def number(value: Any) -> float | None:
43
71
  try:
44
72
  result = float(value)
@@ -64,6 +92,9 @@ def append_segment(result: list[dict[str, Any]], start: Any, end: Any, speaker:
64
92
 
65
93
  def normalize_sortformer(value: Any) -> list[dict[str, Any]]:
66
94
  """Accept NeMo's current tuple/list result variants without inventing data."""
95
+ rttm_text = isinstance(value, str)
96
+ if isinstance(value, str):
97
+ value = [line for line in value.splitlines() if line.strip()]
67
98
  while isinstance(value, list) and len(value) == 1 and isinstance(value[0], (list, tuple)):
68
99
  value = value[0]
69
100
  result: list[dict[str, Any]] = []
@@ -83,12 +114,60 @@ def normalize_sortformer(value: Any) -> list[dict[str, Any]]:
83
114
  duration = number(fields[4])
84
115
  if start is not None and duration is not None:
85
116
  append_segment(result, start, start + duration, fields[7])
86
- if not result and value:
117
+ # A native RTTM command may emit diagnostics but no SPEAKER rows for a
118
+ # genuine silent window. Structured NeMo objects that are non-empty yet
119
+ # unparseable remain a hard contract failure.
120
+ if not result and value and not rttm_text:
87
121
  raise RuntimeError("Sortformer result contained no parseable speaker turns")
88
122
  return result
89
123
 
90
124
 
91
125
  def load_live(args: argparse.Namespace):
126
+ if args.native_binary:
127
+ binary = Path(args.native_binary)
128
+ if not binary.is_file() or not os.access(binary, os.X_OK):
129
+ raise RuntimeError("managed nemo-speech binary is missing or not executable")
130
+ # Metadata inspection validates that this exact Q8 artifact is readable
131
+ # without keeping a second Python/Torch stack on JetPack.
132
+ inspected = subprocess.run(
133
+ [str(binary), "model", "info", args.artifact_path],
134
+ text=True,
135
+ capture_output=True,
136
+ timeout=60,
137
+ check=False,
138
+ )
139
+ if inspected.returncode != 0:
140
+ raise RuntimeError(
141
+ f"nemo-speech rejected the pinned Sortformer model: {(inspected.stderr or inspected.stdout)[-1000:]}"
142
+ )
143
+
144
+ def diarize_native(path: str) -> list[dict[str, Any]]:
145
+ validate_live_wav(path)
146
+ completed = subprocess.run(
147
+ [
148
+ str(binary),
149
+ "diarize",
150
+ path,
151
+ "--model",
152
+ args.artifact_path,
153
+ "--device",
154
+ "cuda:0",
155
+ "--format",
156
+ "rttm",
157
+ ],
158
+ text=True,
159
+ capture_output=True,
160
+ timeout=90,
161
+ check=False,
162
+ )
163
+ if completed.returncode != 0:
164
+ raise RuntimeError(
165
+ f"nemo-speech diarization failed: {(completed.stderr or completed.stdout)[-2000:]}"
166
+ )
167
+ return normalize_sortformer(completed.stdout)
168
+
169
+ return binary, diarize_native, "nemo-speech-cpp-q8-cuda"
170
+
92
171
  import torch
93
172
  from nemo.collections.asr.models import SortformerEncLabelModel
94
173
 
@@ -122,7 +201,10 @@ def load_reconcile(args: argparse.Namespace):
122
201
  def diarize(path: str) -> list[dict[str, Any]]:
123
202
  if not Path(path).is_file():
124
203
  raise ValueError("offline reconciliation audio file does not exist")
125
- output = pipeline(path)
204
+ # pyannote.audio officially supports in-memory waveform mappings. This
205
+ # avoids its optional TorchCodec decoder, which has no aarch64 wheel,
206
+ # without weakening the model or touching JetPack CUDA Torch.
207
+ output = pipeline(load_pcm16_waveform(path))
126
208
  annotation = getattr(output, "speaker_diarization", output)
127
209
  turns = getattr(annotation, "itertracks", None)
128
210
  if not callable(turns):
@@ -142,6 +224,7 @@ def main() -> int:
142
224
  parser.add_argument("--artifact-path", required=True)
143
225
  parser.add_argument("--revision", required=True)
144
226
  parser.add_argument("--model-digest", required=True)
227
+ parser.add_argument("--native-binary")
145
228
  args = parser.parse_args()
146
229
 
147
230
  # Do not allow an accidentally inherited setup token to become a request
@@ -17,6 +17,12 @@ import sys
17
17
 
18
18
  MODEL = "ViT-B-32"
19
19
  PRETRAINED = "laion2b_s34b_b79k"
20
+ MODEL_REPOSITORY = "laion/CLIP-ViT-B-32-laion2B-s34B-b79K"
21
+ MODEL_REVISION = "1a25a446712ba5ee05982a381eed697ef9b435cf"
22
+ MODEL_WEIGHTS_FILENAME = "open_clip_pytorch_model.bin"
23
+ MODEL_WEIGHTS_BYTES = 605219813
24
+ MODEL_WEIGHTS_SHA256 = "1bd3c7172de5b207ceac554f5ab5266166f3b9baccc9af5989bc801016d080ad"
25
+ MODEL_DIGEST = "sha256:" + MODEL_WEIGHTS_SHA256
20
26
  EMBEDDING_DIMENSION = 512
21
27
 
22
28
 
@@ -32,36 +38,75 @@ def deny_network():
32
38
  socket.socket.connect_ex = denied
33
39
 
34
40
 
35
- def artifact_entries(cache_dir):
36
- entries = []
37
- for root, _dirs, names in os.walk(cache_dir):
38
- for name in sorted(names):
39
- path = os.path.join(root, name)
40
- if not os.path.isfile(path) or os.path.getsize(path) < 1024:
41
- continue
42
- relative = os.path.relpath(path, cache_dir).replace(os.sep, "/")
43
- digest = hashlib.sha256()
44
- with open(path, "rb") as source:
45
- while True:
46
- block = source.read(1024 * 1024)
47
- if not block:
48
- break
49
- digest.update(block)
50
- entries.append({"path": relative, "bytes": os.path.getsize(path), "sha256": digest.hexdigest()})
51
- return sorted(entries, key=lambda item: item["path"])
52
-
53
-
54
- def artifact_digest(entries):
41
+ def sha256_file(path):
55
42
  digest = hashlib.sha256()
56
- for entry in entries:
57
- digest.update(entry["path"].encode("utf-8"))
58
- digest.update(b"\0")
59
- digest.update(entry["sha256"].encode("ascii"))
60
- digest.update(b"\n")
61
- return "sha256:" + digest.hexdigest()
43
+ with open(path, "rb") as source:
44
+ while True:
45
+ block = source.read(1024 * 1024)
46
+ if not block:
47
+ break
48
+ digest.update(block)
49
+ return digest.hexdigest()
50
+
51
+
52
+ def model_weights_path(cache_dir):
53
+ return os.path.join(cache_dir, MODEL_WEIGHTS_FILENAME)
54
+
55
+
56
+ def verify_model_weights(cache_dir):
57
+ path = model_weights_path(cache_dir)
58
+ if not os.path.isfile(path):
59
+ raise RuntimeError("Pinned OpenCLIP weight is missing; run explicit vision setup")
60
+ actual_bytes = os.path.getsize(path)
61
+ if actual_bytes != MODEL_WEIGHTS_BYTES:
62
+ raise RuntimeError(
63
+ "Pinned OpenCLIP weight has an unexpected size "
64
+ "(expected %d bytes, got %d); run explicit vision setup" % (MODEL_WEIGHTS_BYTES, actual_bytes)
65
+ )
66
+ actual_sha256 = sha256_file(path)
67
+ if actual_sha256 != MODEL_WEIGHTS_SHA256:
68
+ raise RuntimeError(
69
+ "Pinned OpenCLIP weight checksum mismatch "
70
+ "(expected %s, got %s); run explicit vision setup" % (MODEL_WEIGHTS_SHA256, actual_sha256)
71
+ )
72
+ return path
73
+
74
+
75
+ def artifact_entries(cache_dir):
76
+ path = verify_model_weights(cache_dir)
77
+ return [{
78
+ "path": MODEL_WEIGHTS_FILENAME,
79
+ "bytes": os.path.getsize(path),
80
+ "sha256": MODEL_WEIGHTS_SHA256,
81
+ }]
82
+
83
+
84
+ def download_pinned_model_weights(cache_dir):
85
+ os.makedirs(cache_dir, exist_ok=True)
86
+ try:
87
+ verified = verify_model_weights(cache_dir)
88
+ except RuntimeError:
89
+ # An interrupted/corrupt setup may leave a file at the managed target.
90
+ # Only explicit setup is permitted to replace it.
91
+ force_download = True
92
+ else:
93
+ return verified
94
+ from huggingface_hub import hf_hub_download
95
+ downloaded = hf_hub_download(
96
+ repo_id=MODEL_REPOSITORY,
97
+ filename=MODEL_WEIGHTS_FILENAME,
98
+ revision=MODEL_REVISION,
99
+ local_dir=cache_dir,
100
+ local_files_only=False,
101
+ force_download=force_download,
102
+ )
103
+ expected_path = model_weights_path(cache_dir)
104
+ if os.path.abspath(downloaded) != os.path.abspath(expected_path):
105
+ raise RuntimeError("Pinned OpenCLIP download did not materialize in the managed cache")
106
+ return verify_model_weights(cache_dir)
62
107
 
63
108
 
64
- def load_model(cache_dir, offline):
109
+ def load_model(weights_path, offline):
65
110
  if offline:
66
111
  deny_network()
67
112
  os.environ["HF_HUB_OFFLINE"] = "1"
@@ -70,11 +115,14 @@ def load_model(cache_dir, offline):
70
115
  import open_clip
71
116
  if not torch.cuda.is_available():
72
117
  raise RuntimeError("JetPack CUDA Torch is unavailable for OpenCLIP")
118
+ if os.environ.get("CUDA_VISIBLE_DEVICES") != "0":
119
+ raise RuntimeError("OpenCLIP requires CUDA_VISIBLE_DEVICES=0")
120
+ if torch.cuda.current_device() != 0:
121
+ raise RuntimeError("OpenCLIP did not bind to logical CUDA device 0")
73
122
  device = torch.device("cuda:0")
74
123
  model, _, preprocess = open_clip.create_model_and_transforms(
75
124
  MODEL,
76
- pretrained=PRETRAINED,
77
- cache_dir=cache_dir,
125
+ pretrained=weights_path,
78
126
  device=device,
79
127
  )
80
128
  model.eval()
@@ -82,27 +130,33 @@ def load_model(cache_dir, offline):
82
130
 
83
131
 
84
132
  def setup(cache_dir):
85
- torch, model, _preprocess, device = load_model(cache_dir, False)
133
+ _weights_path = download_pinned_model_weights(cache_dir)
134
+ import torch
135
+ if not torch.cuda.is_available():
136
+ raise RuntimeError("JetPack CUDA Torch is unavailable for OpenCLIP")
137
+ if os.environ.get("CUDA_VISIBLE_DEVICES") != "0":
138
+ raise RuntimeError("OpenCLIP setup requires CUDA_VISIBLE_DEVICES=0")
139
+ if torch.cuda.current_device() != 0:
140
+ raise RuntimeError("OpenCLIP setup did not bind to logical CUDA device 0")
86
141
  entries = artifact_entries(cache_dir)
87
- if not entries:
88
- raise RuntimeError("OpenCLIP setup did not create verifiable model artifacts")
89
- with torch.inference_mode():
90
- # Model loading is setup verification, not a user inference request.
91
- torch.cuda.synchronize(device)
92
142
  major, minor = torch.cuda.get_device_capability(0)
93
143
  emit({
94
144
  "type": "setup",
95
145
  "success": True,
96
146
  "model": MODEL,
97
147
  "pretrained": PRETRAINED,
148
+ "model_repository": MODEL_REPOSITORY,
149
+ "model_revision": MODEL_REVISION,
150
+ "model_weights_sha256": MODEL_WEIGHTS_SHA256,
98
151
  "backend": "open-clip",
99
152
  "embedding_dimension": EMBEDDING_DIMENSION,
100
153
  "normalization": "l2",
101
154
  "device": torch.cuda.get_device_name(0),
102
155
  "compute_capability": "%d.%d" % (major, minor),
103
156
  "torch_cuda_version": str(torch.version.cuda),
157
+ "cuda_visible_devices": os.environ.get("CUDA_VISIBLE_DEVICES"),
104
158
  "artifacts": entries,
105
- "model_digest": artifact_digest(entries),
159
+ "model_digest": MODEL_DIGEST,
106
160
  })
107
161
 
108
162
 
@@ -117,13 +171,12 @@ def image_from_input(input_):
117
171
  raise ValueError("Provide path or bytesBase64")
118
172
 
119
173
 
120
- def embed(cache_dir, expected_digest):
121
- entries = artifact_entries(cache_dir)
122
- actual = artifact_digest(entries)
123
- if actual != expected_digest:
124
- raise RuntimeError("OpenCLIP model artifacts are missing or changed; run explicit vision setup")
174
+ def embed(cache_dir, expected_digest, expected_revision):
175
+ if expected_digest != MODEL_DIGEST or expected_revision != MODEL_REVISION:
176
+ raise RuntimeError("OpenCLIP model identity does not match the pinned setup contract")
177
+ weights_path = verify_model_weights(cache_dir)
125
178
  input_ = json.loads(sys.stdin.read() or "{}")
126
- torch, model, preprocess, device = load_model(cache_dir, True)
179
+ torch, model, preprocess, device = load_model(weights_path, True)
127
180
  image = image_from_input(input_)
128
181
  with torch.inference_mode():
129
182
  tensor = preprocess(image).unsqueeze(0).to(device)
@@ -137,8 +190,11 @@ def embed(cache_dir, expected_digest):
137
190
  "success": True,
138
191
  "model": MODEL,
139
192
  "pretrained": PRETRAINED,
193
+ "model_repository": MODEL_REPOSITORY,
194
+ "model_revision": MODEL_REVISION,
195
+ "model_weights_sha256": MODEL_WEIGHTS_SHA256,
140
196
  "backend": "open-clip",
141
- "model_digest": actual,
197
+ "model_digest": MODEL_DIGEST,
142
198
  "embedding": values,
143
199
  "dimension": EMBEDDING_DIMENSION,
144
200
  "normalization": "l2",
@@ -151,15 +207,16 @@ def main():
151
207
  parser.add_argument("--embed", action="store_true")
152
208
  parser.add_argument("--cache-dir", required=True)
153
209
  parser.add_argument("--model-digest")
210
+ parser.add_argument("--model-revision")
154
211
  args = parser.parse_args()
155
212
  if args.setup == args.embed:
156
213
  raise ValueError("Choose exactly one of --setup or --embed")
157
214
  if args.setup:
158
215
  setup(args.cache_dir)
159
216
  else:
160
- if not args.model_digest:
161
- raise ValueError("--model-digest is required for offline embedding")
162
- embed(args.cache_dir, args.model_digest)
217
+ if not args.model_digest or not args.model_revision:
218
+ raise ValueError("--model-digest and --model-revision are required for offline embedding")
219
+ embed(args.cache_dir, args.model_digest, args.model_revision)
163
220
 
164
221
 
165
222
  if __name__ == "__main__":
@@ -245088,6 +245088,7 @@ var SETUP_TIMEOUT_MS = 20 * 6e4;
245088
245088
  // packages/execution/dist/speaker-diarization-runtime.js
245089
245089
  init_model_store();
245090
245090
  init_process_async();
245091
+ init_venv_paths();
245091
245092
 
245092
245093
  // packages/execution/dist/audio-semantic-embedding-runtime.js
245093
245094
  init_process_async();
@@ -245095,6 +245096,27 @@ init_jetson_monitor();
245095
245096
  init_model_store();
245096
245097
  init_venv_paths();
245097
245098
  var SETUP_TIMEOUT_MS2 = 30 * 6e4;
245099
+ var CLAP_RUNTIME_WHEELS = [
245100
+ { distribution: "numpy", version: "1.26.4", importName: "numpy", filename: "numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", source: "https://files.pythonhosted.org/packages/fc/a5/4beee6488160798683eed5bdb7eead455892c3b4e1f78d79d8d3f3b084ac/numpy-1.26.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", sha256: "d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4" },
245101
+ { distribution: "transformers", version: "4.57.3", importName: "transformers", filename: "transformers-4.57.3-py3-none-any.whl", source: "https://files.pythonhosted.org/packages/6a/6b/2f416568b3c4c91c96e5a365d164f8a4a4a88030aa8ab4644181fdadce97/transformers-4.57.3-py3-none-any.whl", sha256: "c77d353a4851b1880191603d36acb313411d3577f6e2897814f333841f7003f4" },
245102
+ { distribution: "huggingface-hub", version: "0.36.0", importName: "huggingface_hub", filename: "huggingface_hub-0.36.0-py3-none-any.whl", source: "https://files.pythonhosted.org/packages/cb/bd/1a875e0d592d447cbc02805fd3fe0f497714d6a2583f59d14fa9ebad96eb/huggingface_hub-0.36.0-py3-none-any.whl", sha256: "7bcc9ad17d5b3f07b57c78e79d527102d08313caa278a641993acddcb894548d" },
245103
+ { distribution: "hf-xet", version: "1.1.5", importName: "hf_xet", filename: "hf_xet-1.1.5-cp37-abi3-manylinux_2_28_aarch64.whl", source: "https://files.pythonhosted.org/packages/d0/54/0fcf2b619720a26fbb6cc941e89f2472a522cd963a776c089b189559447f/hf_xet-1.1.5-cp37-abi3-manylinux_2_28_aarch64.whl", sha256: "dbba1660e5d810bd0ea77c511a99e9242d920790d0e63c0e4673ed36c4022d18" },
245104
+ { distribution: "tokenizers", version: "0.22.1", importName: "tokenizers", filename: "tokenizers-0.22.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", source: "https://files.pythonhosted.org/packages/1e/3b/55e64befa1e7bfea963cf4b787b2cea1011362c4193f5477047532ce127e/tokenizers-0.22.1-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", sha256: "19d2962dd28bc67c1f205ab180578a78eef89ac60ca7ef7cbe9635a46a56422a" },
245105
+ { distribution: "safetensors", version: "0.5.3", importName: "safetensors", filename: "safetensors-0.5.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", source: "https://files.pythonhosted.org/packages/5d/9a/add3e6fef267658075c5a41573c26d42d80c935cdc992384dfae435feaef/safetensors-0.5.3-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", sha256: "11bce6164887cd491ca75c2326a113ba934be596e22b28b1742ce27b1d076467" },
245106
+ { distribution: "filelock", version: "3.16.1", importName: "filelock", filename: "filelock-3.16.1-py3-none-any.whl", source: "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", sha256: "2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0" },
245107
+ { distribution: "fsspec", version: "2024.10.0", importName: "fsspec", filename: "fsspec-2024.10.0-py3-none-any.whl", source: "https://files.pythonhosted.org/packages/c6/b2/454d6e7f0158951d8a78c2e1eb4f69ae81beb8dca5fee9809c6c99e9d0d0/fsspec-2024.10.0-py3-none-any.whl", sha256: "03b9a6785766a4de40368b88906366755e2819e758b83705c88cd7cb5fe81871" },
245108
+ { distribution: "packaging", version: "24.2", importName: "packaging", filename: "packaging-24.2-py3-none-any.whl", source: "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", sha256: "09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759" },
245109
+ { distribution: "PyYAML", version: "6.0.2", importName: "yaml", filename: "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", source: "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", sha256: "8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237" },
245110
+ { distribution: "regex", version: "2024.11.6", importName: "regex", filename: "regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", source: "https://files.pythonhosted.org/packages/78/a2/6dd36e16341ab95e4c6073426561b9bfdeb1a9c9b63ab1b579c2e96cb105/regex-2024.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", sha256: "d3660c82f209655a06b587d55e723f0b813d3a7db2e32e5e7dc64ac2a9e86fde" },
245111
+ { distribution: "requests", version: "2.32.3", importName: "requests", filename: "requests-2.32.3-py3-none-any.whl", source: "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", sha256: "70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" },
245112
+ { distribution: "tqdm", version: "4.67.1", importName: "tqdm", filename: "tqdm-4.67.1-py3-none-any.whl", source: "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", sha256: "26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2" },
245113
+ { distribution: "typing-extensions", version: "4.12.2", importName: "typing_extensions", filename: "typing_extensions-4.12.2-py3-none-any.whl", source: "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", sha256: "04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d" },
245114
+ { distribution: "certifi", version: "2024.8.30", importName: "certifi", filename: "certifi-2024.8.30-py3-none-any.whl", source: "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", sha256: "922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8" },
245115
+ { distribution: "charset-normalizer", version: "3.4.0", importName: "charset_normalizer", filename: "charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", source: "https://files.pythonhosted.org/packages/c2/72/12a7f0943dd71fb5b4e7b55c41327ac0a1663046a868ee4d0d8e9c369b85/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", sha256: "40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca" },
245116
+ { distribution: "idna", version: "3.10", importName: "idna", filename: "idna-3.10-py3-none-any.whl", source: "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", sha256: "946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3" },
245117
+ { distribution: "urllib3", version: "2.2.3", importName: "urllib3", filename: "urllib3-2.2.3-py3-none-any.whl", source: "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", sha256: "ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac" }
245118
+ ];
245119
+ var CLAP_PYTHON_REQUIREMENTS = CLAP_RUNTIME_WHEELS.map((wheel) => `${wheel.distribution}==${wheel.version}`);
245098
245120
 
245099
245121
  // packages/execution/dist/speaker-embedding-runtime.js
245100
245122
  init_jetson_monitor();