Stub — a human will curate the wording before publishing.
What it does
Every workflow worker that callscw.models.load("<id>") needs the
weight file on disk before the worker container starts. Edge Core’s
Model Manager resolves each ID into the local cache at
~/.cyberwave/models/{model_id}/ and serves it read-only into the
worker. Sources are tried in priority order; the first one that yields
a checksum-verified file wins.
Resolution order
For each required model:- Pre-staged on disk. A file already at
~/.cyberwave/models/{model_id}/is registered asdownloaded_from: prestagedand short-circuits the catalog entirely. Use this for air-gapped sites. - Cyberwave-hosted signed URL (
GET /api/v1/mlmodels/{uuid}/weights). Authenticated artefact in our private GCS bucket — preferred when we have mirrored the checkpoint. - Upstream weights URL (
download_url/metadata.upstream_weights_url). Public community mirror — used for ONNX models we publish tostatic.cyberwave.com/ml_models/. - Runtime-managed download (new): when the catalog entry has no URL of any kind but its
edge_runtimeships its own weight resolver (today:ultralyticsagainst its GitHub releases hub), Edge Core invokes that resolver in a subprocess and caches the result asdownloaded_from: runtime_managed. This is what lets.ptcatalog entries (YOLO26, YOLOE-26) work without a mirrored upstream URL.
ensure_model call. Pre-staged files are never auto-overwritten by catalog updates.
ML runtime extras
The default install keeps the runtime surface lean — no Torch, no Ultralytics, no ONNX. Catalog entries that rely on the runtime-managed download fallback need the matching runtime installed on the edge host:RuntimeError listing three workarounds: drop the file under ~/.cyberwave/models/{model_id}/, upload to /api/v1/mlmodels/{uuid}/weights, or set metadata.download_url on the catalog entry.
Pre-staging weights (air-gapped sites)
.pt → ultralytics, .onnx → onnxruntime, …), and writes a sidecar metadata.json so subsequent runs are deterministic.
Self-healing the cache
A failed download leaves an emptycache_dir/{model_id}/ behind — mkdir runs before the network fetch, and any error in the downloader skips the cleanup. Left alone, the SDK in the worker container would later route that directory into torch.load and crash with IsADirectoryError on every restart.
Edge Core handles this in three layers:
- Per-download cleanup (conservative). A failed
_download_model/_download_runtime_managedremoves the staging directory before the exception propagates, provided it contains only an.dl_*.partpartial download, ametadata.jsonsidecar, or nothing at all. Operator-staged content blocks the prune. - Startup sweep (conservative).
ModelManager()walkscache_dir/once at construction time and prunes any per-model subdirectory that is not in the manifest and contains only orphan cruft. This is what unsticks hosts that were already wedged before this code shipped. Operator-staged content blocks the prune. evict_model('foo')(decisive). When there is no manifest entry butcache_dir/foo/exists on disk, the directory is removed unconditionally. This is the recovery hook for a remote eviction API to call without shell access to the host; an explicitevictis treated as a stronger operator-intent signal than the conservative auto-sweeps.
ModelManager._resolve_model_path so an orphan dir that survives Edge Core (e.g., on a host that hasn’t picked up this release yet but mounts a fixed SDK) is also recovered inside the worker container. The Ultralytics runtime is the defensive backstop: if a directory ever reaches it (a hand-built UltralyticsRuntime().load(...) call bypassing the manager), it raises a clear FileNotFoundError instead of letting Ultralytics call torch.load(<dir>).
Sidecar fields
Every cached weight has ametadata.json next to it. Fields you’ll see:
| Field | Meaning |
|---|---|
downloaded_from | artifact_url, download_url, runtime_managed, or prestaged |
source_url | Public URL we fetched (or null for artifact_url and runtime_managed — neither is a re-fetchable persistent URL) |
upstream_url | Provenance hint |
checksum_sha256 | SHA-256 of the on-disk bytes; re-verified on every load |
runtime | ultralytics, onnxruntime, tflite, tensorrt, torch, opencv |
cyberwave-edge-core/cyberwave_edge_core/model_manager.py.