@camstack/addon-ai 0.4.125 → 0.4.126

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.
@@ -1,18 +1,15 @@
1
1
  <!--
2
2
  THIRD_PARTY_MODELS.md: the product notice for every model CamStack can download.
3
3
 
4
- HAND-WRITTEN FOR NOW. Task 7 of docs/superpowers/plans/2026-09-26-model-license-compliance.md
5
- replaces this file with generator output (scripts/gen-model-licenses.ts), built from the
6
- licence records on the model catalogs. Until then this root file is the single source:
7
- - packages/addon-pipeline, packages/addon-post-analysis, packages/addon-ai and server/backend
8
- each carry a byte-identical COPY (npm cannot ship a file from outside the package).
9
- Edit this root file, then copy it: for d in packages/addon-pipeline packages/addon-post-analysis
10
- packages/addon-ai server/backend; do cp THIRD_PARTY_MODELS.md "$d/"; done
11
- scripts/check-model-notices-shipped.ts fails CI when a copy drifts.
12
- - The Hugging Face mirror (camstack/camstack-models) receives this same file, staged by
13
- hf/camstack-models/upload.sh. Its model card points at the "Source offer" section below.
14
- Facts: docs/superpowers/specs/2026-09-26-model-license-compliance.md (verified 2026-09-26).
15
- Not legal advice.
4
+ GENERATED by scripts/gen-model-licenses.ts from the licence records on the model
5
+ catalogs (D661). Do not edit it: change the record in the catalog
6
+ (packages/addon-pipeline/src/detection-pipeline/registry/model-licenses.ts,
7
+ packages/addon-post-analysis/src/embedding-encoder/catalogs/model-licenses.ts,
8
+ packages/addon-ai/src/runtime/llm-model-licenses.ts), then run npm run models:notices.
9
+ The package copies (packages/addon-pipeline, packages/addon-post-analysis, packages/addon-ai, packages/addon-model-studio, server/backend) are byte-identical
10
+ (npm cannot ship a file from outside the package); the Hugging Face mirror receives
11
+ the same file from hf/camstack-models/upload.sh. Drift fails CI.
12
+ Facts: docs/superpowers/specs/2026-09-26-model-license-compliance.md. Not legal advice.
16
13
  -->
17
14
 
18
15
  # Third-party models
@@ -33,64 +30,35 @@ under [Non-commercial models](#non-commercial-models).
33
30
 
34
31
  ## Required attributions
35
32
 
36
- - **Ultralytics YOLO26, YOLOv9 and YOLOv8** — © Ultralytics. Licensed under
37
- AGPL-3.0 (`AGPL-3.0.txt`). See the [source offer](#source-offer-for-the-agpl-30-weights).
38
- https://github.com/ultralytics/ultralytics
39
- - **YOLOv9** (architecture) — Chien-Yao Wang, I-Hau Yeh, Hong-Yuan Mark Liao,
40
- GPL-3.0 (`GPL-3.0.txt`). https://github.com/WongKinYiu/yolov9
41
- - **SCRFD / InsightFace** — code MIT. The pretrained weights are released by
42
- InsightFace for non-commercial research purposes only (`InsightFace-terms.txt`).
43
- https://github.com/deepinsight/insightface
44
- - **MobileCLIP** — © Apple Inc. *Apple Machine Learning Research Model is
45
- licensed under the Apple Machine Learning Research Model License Agreement.*
46
- (`Apple-AMLR.txt`). CamStack's MobileCLIP files are **Model Derivatives**:
47
- the image encoders are converted to OpenVINO IR and CoreML at FP16; the text
48
- encoders are quantised to INT8 ONNX and converted to OpenVINO IR.
49
- https://github.com/apple/ml-mobileclip
50
- - **Llama 3.2** — **Built with Llama.** Llama 3.2 is licensed under the Llama
51
- 3.2 Community License, Copyright © Meta Platforms, Inc. All Rights Reserved.
52
- (`Llama-3.2-Community.txt`; Acceptable Use Policy:
53
- https://www.llama.com/llama3_2/use-policy)
54
- - **fast-plate-ocr** — Copyright (c) 2024 ankandrew, MIT (`MIT-fast-plate-ocr.txt`).
55
- https://github.com/ankandrew/fast-plate-ocr
56
- - **RF-DETR** — © Roboflow, Apache-2.0. https://github.com/roboflow/rf-detr
57
- - **YuNet** — weights Copyright (c) 2020 Shiqi Yu, MIT (`MIT-yunet-reference.txt`).
58
- https://github.com/opencv/opencv_zoo/tree/main/models/face_detection_yunet ·
59
- [license](https://github.com/opencv/opencv_zoo/blob/main/models/face_detection_yunet/LICENSE).
60
- Training code BSD-3-Clause (`BSD-3-Clause.txt`),
61
- https://github.com/ShiqiYu/libfacedetection.train.
62
- Trained on WIDER FACE, whose images are CC BY-NC-ND.
63
- - **AuraFace v1** — fal.ai, Apache-2.0. https://huggingface.co/fal/AuraFace-v1
64
- - **SigLIP 2** — © Google LLC, Apache-2.0 (`Apache-2.0.txt`).
65
- https://huggingface.co/google/siglip2-base-patch16-224 ·
66
- https://github.com/google-research/big_vision. CamStack's SigLIP 2 files are
67
- modified: the vision input scaling `2x - 1` is baked into the graph, the text
68
- graph slices its input to the model's 64 positions, the tokenizer lower-cases,
69
- and the towers are converted to ONNX, OpenVINO IR and CoreML FP16.
70
- - **EasyOCR** — JaidedAI, Apache-2.0. https://github.com/JaidedAI/EasyOCR
71
- - **U²-Net** — Xuebin Qin et al., Apache-2.0. https://github.com/xuebinqin/U-2-Net
72
- - **YAMNet** — © Google LLC, Apache-2.0.
73
- https://github.com/tensorflow/models/tree/master/research/audioset/yamnet
74
- - **AIY Vision Birds V1** and the **Coral Edge TPU models** — © Google LLC,
75
- Apache-2.0. https://github.com/google-coral/test_data
76
- - **EfficientNet-Lite0** via **timm** — Ross Wightman, Apache-2.0.
77
- https://github.com/huggingface/pytorch-image-models
78
- - **torchvision MobileNetV3** — BSD-3-Clause (`BSD-3-Clause.txt`). https://github.com/pytorch/vision
79
- - **Scrypted plugin models** — Koushik Dutta, repository tagged MIT
80
- (`MIT-scrypted-plugin-models.txt`). https://huggingface.co/scrypted/plugin-models
81
- - **Qwen2.5, Qwen3-VL, Qwen3.6** — Alibaba Cloud, Apache-2.0. https://huggingface.co/Qwen
82
- - **Open Images V7** (animal-classifier training data) — annotations © Google
83
- LLC, licensed under CC BY 4.0 (`CC-BY-4.0.txt`). Images are listed by Google
84
- as CC BY 2.0, without warranty.
85
- https://storage.googleapis.com/openimages/web/factsfigures_v7.html
86
- - **Vehicle classification dataset** (vehicle-type-v1 training data) — by
87
- DrBimmer, https://huggingface.co/datasets/DrBimmer/vehicle-classification,
88
- licensed under CC BY-NC 4.0 (`CC-BY-NC-4.0.txt`). CamStack fine-tuned a model
89
- on it; the resulting weights are treated as non-commercial.
90
- - **AudioSet** ontology and labels (YAMNet) — © Google LLC, CC BY 4.0.
91
- https://research.google.com/audioset/
92
- - **COCO** annotations (YOLO pretraining) — COCO Consortium, CC BY 4.0. Images
93
- remain under the terms of their Flickr owners. https://cocodataset.org/#termsofuse
33
+ - © Ultralytics, AGPL-3.0. Corresponding source: the upstream Ultralytics checkpoint and scripts/build-camstack-models.py in https://github.com/camstack/server. https://github.com/ultralytics/ultralytics
34
+ - Coral Edge TPU models and AIY Vision Birds V1 © Google LLC, Apache-2.0. https://github.com/google-coral/test_data
35
+ - © Ultralytics, AGPL-3.0 (Ultralytics YOLOv9 weights). YOLOv9 architecture: Chien-Yao Wang, I-Hau Yeh, Hong-Yuan Mark Liao, GPL-3.0 (https://github.com/WongKinYiu/yolov9). Corresponding source: the upstream Ultralytics checkpoint and scripts/build-camstack-models.py in https://github.com/camstack/server. https://github.com/ultralytics/ultralytics
36
+ - © Ultralytics, AGPL-3.0 (YOLOv8n base, fine-tuned by CamStack with Ultralytics). The fine-tuning checkpoint is not published yet. https://github.com/ultralytics/ultralytics
37
+ - RF-DETR © Roboflow, Apache-2.0. https://github.com/roboflow/rf-detr
38
+ - SCRFD © InsightFace. Pretrained models released for non-commercial research purposes only. https://github.com/deepinsight/insightface/tree/master/detection/scrfd
39
+ - YuNet weights Copyright (c) 2020 Shiqi Yu, MIT. Training code: ShiqiYu/libfacedetection.train, BSD-3-Clause. https://github.com/opencv/opencv_zoo/tree/main/models/face_detection_yunet
40
+ - AuraFace v1 by fal.ai, Apache-2.0. https://huggingface.co/fal/AuraFace-v1
41
+ - Scrypted plugin models, Koushik Dutta: repository tagged MIT (licenses/models/MIT-scrypted-plugin-models.txt), no per-model terms. https://huggingface.co/scrypted/plugin-models
42
+ - © Ultralytics, AGPL-3.0 (YOLOv8n base, fine-tuned for plates by an unidentified third party). CamStack holds no training checkpoint; the ONNX file is the only form it has. https://github.com/ultralytics/ultralytics
43
+ - fast-plate-ocr, MIT License, copyright (c) 2024 ankandrew (full notice: licenses/models/MIT-fast-plate-ocr.txt). https://github.com/ankandrew/fast-plate-ocr
44
+ - EasyOCR © JaidedAI, Apache-2.0. https://github.com/JaidedAI/EasyOCR
45
+ - EfficientNet-Lite0 via timm (Ross Wightman), Apache-2.0. Open Images V7 annotations © Google LLC, CC BY 4.0; images listed by Google as CC BY 2.0, without warranty. https://github.com/huggingface/pytorch-image-models
46
+ - torchvision MobileNetV3, BSD-3-Clause. Trained on the Vehicle classification dataset by DrBimmer (https://huggingface.co/datasets/DrBimmer/vehicle-classification), CC BY-NC 4.0. https://github.com/pytorch/vision
47
+ - Apple Machine Learning Research Model is licensed under the Apple Machine Learning Research Model License Agreement. https://github.com/apple/ml-mobileclip
48
+ - SigLIP 2 © Google LLC, Apache-2.0. https://huggingface.co/google/siglip2-base-patch16-224
49
+ - U²-Net © Xuebin Qin et al., Apache-2.0. https://github.com/xuebinqin/U-2-Net
50
+ - YAMNet © Google LLC, Apache-2.0. AudioSet ontology and labels © Google LLC, CC BY 4.0. https://github.com/tensorflow/models/tree/master/research/audioset/yamnet
51
+ - Qwen models © Alibaba Cloud, Apache-2.0. https://huggingface.co/Qwen · https://huggingface.co/unsloth · https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF
52
+ - Built with Llama. Llama 3.2 is licensed under the Llama 3.2 Community License, Copyright © Meta Platforms, Inc. All Rights Reserved. https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF
53
+ - Scrypted YOLOv9 ReLU detectors, Koushik Dutta (scrypted/plugin-models, repository tagged MIT); trained with the YOLOv9 code of Chien-Yao Wang, I-Hau Yeh, Hong-Yuan Mark Liao, GPL-3.0 (https://github.com/WongKinYiu/yolov9). https://huggingface.co/scrypted/plugin-models
54
+
55
+ Training data under attribution terms:
56
+
57
+ - **COCO 2017** (training data of `yolo26n` and 53 more): annotations CC-BY-4.0; images under their Flickr owners' terms. https://cocodataset.org/#termsofuse
58
+ - **WIDER FACE** (training data of `scrfd-2.5g` and 1 more): research-oriented terms; images CC BY-NC-ND. http://shuoyang1213.me/WIDERFACE/
59
+ - **Open Images V7** (training data of `animal-classifier`): annotations CC-BY-4.0 (Google LLC); images listed as CC-BY-2.0, no warranty. https://storage.googleapis.com/openimages/web/factsfigures_v7.html
60
+ - **DrBimmer/vehicle-classification** (training data of `vehicle-type-v1`): CC-BY-NC-4.0 — treated as binding the trained weights (conservative reading). https://huggingface.co/datasets/DrBimmer/vehicle-classification
61
+ - **AudioSet ontology/labels** (training data of `yamnet-onnx`): CC-BY-4.0 (Google LLC). https://research.google.com/audioset/
94
62
 
95
63
  ## Source offer for the AGPL-3.0 weights
96
64
 
@@ -100,9 +68,7 @@ under [Non-commercial models](#non-commercial-models).
100
68
  cards link here instead of repeating it.
101
69
  -->
102
70
 
103
- The folders `objectDetection/yolo26`, `objectDetection/yolov9`,
104
- `segmentation/yolo26-seg`, `plateDetection/yolov8-plate` and
105
- `packageDetection/yolov8-package` of the model mirror hold Ultralytics weights,
71
+ The folders `objectDetection/yolo26`, `objectDetection/yolov9`, `packageDetection/yolov8-package`, `plateDetection/yolov8-plate` and `segmentation/yolo26-seg` of the model mirror hold Ultralytics weights,
106
72
  modified by CamStack and distributed under AGPL-3.0. Their Corresponding Source
107
73
  is the public CamStack source repository, **https://github.com/camstack/server**
108
74
  (MIT), together with the upstream checkpoints it starts from:
@@ -136,106 +102,143 @@ What the repository does **not** cover yet:
136
102
  These are downloaded by default or selectable, and their terms **do not allow
137
103
  commercial use**:
138
104
 
139
- | Model | Terms |
140
- | --- | --- |
141
- | `scrfd-2.5g` (face detection, selectable, not the default since 2026-09-26) | InsightFace pretrained models: non-commercial research purposes only |
142
- | `mobileclip-s1`, `mobileclip-s2`, `mobileclip-s1-text`, `mobileclip-s2-text` (semantic search, `mobileclip-s1` default) | Apple Machine Learning Research Model License: research purposes only, no commercial product or service |
143
- | `vehicle-type-v1` (vehicle classifier) | trained on a CC BY-NC 4.0 dataset; weights treated as non-commercial |
144
- | `bird-nabirds-404` (hidden, pending removal) | NABirds: no reproduction, distribution or products without the Cornell Lab's written permission |
105
+ | Model | Used for | Terms |
106
+ | --- | --- | --- |
107
+ | `scrfd-2.5g` | Face detection | LicenseRef-InsightFace-NonCommercial-Research; training data: research-oriented terms; images CC BY-NC-ND ([terms](https://github.com/deepinsight/insightface#license)) |
108
+ | `vehicle-type-v1` (default) | Vehicle classifier | CC-BY-NC-4.0; training data: CC-BY-NC-4.0 — treated as binding the trained weights (conservative reading) ([terms](https://creativecommons.org/licenses/by-nc/4.0/)) |
109
+ | `mobileclip-s1` (default) | Semantic search, image encoders (CLIP) | LicenseRef-Apple-AMLR ([terms](https://github.com/apple/ml-mobileclip/blob/main/LICENSE_MODELS)) |
110
+ | `mobileclip-s2` | Semantic search, image encoders (CLIP) | LicenseRef-Apple-AMLR ([terms](https://github.com/apple/ml-mobileclip/blob/main/LICENSE_MODELS)) |
111
+ | `mobileclip-s1-text` | Semantic search, text encoders (CLIP) | LicenseRef-Apple-AMLR ([terms](https://github.com/apple/ml-mobileclip/blob/main/LICENSE_MODELS)) |
112
+ | `mobileclip-s2-text` | Semantic search, text encoders (CLIP) | LicenseRef-Apple-AMLR ([terms](https://github.com/apple/ml-mobileclip/blob/main/LICENSE_MODELS)) |
145
113
 
146
114
  ## Models
147
115
 
148
116
  "Mirror" means https://huggingface.co/camstack/camstack-models, folder given.
149
117
  "Code / weights" gives the two licences separately because they often differ.
150
118
  **Unknown** means no licence could be traced; it does not mean free to use.
119
+ *default* marks the model a step runs when nobody chose one; *hidden* marks an
120
+ entry kept resolvable for a saved selection but no longer offered.
151
121
 
152
122
  ### Object detection
153
123
 
154
124
  | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
155
125
  | --- | --- | --- | --- | --- | --- |
156
- | `yolo26n`, `yolo26s`, `yolo26m`, `yolo26l`, `yolo26x`, with every `-fp16`, `-int8`, `-320`, `-256`, `-320-int8`, `-256-int8` variant | Ultralytics YOLO26, COCO-pretrained | AGPL-3.0 / AGPL-3.0 | COCO 2017 (annotations CC BY 4.0) | exported to ONNX, OpenVINO IR (FP32/FP16) and CoreML FP16; `-320`/`-256` re-exported at that input size; `-int8` OpenVINO NNCF post-training INT8 | Mirror `objectDetection/yolo26` |
157
- | `yolov9{t,s,m,c}-320`, `yolov9{t,s,m,c}-640`, and their `-int8` twins | Ultralytics YOLOv9 weights, COCO-pretrained; architecture by WongKinYiu | AGPL-3.0 / AGPL-3.0 (original YOLOv9 repository GPL-3.0) | COCO 2017 | exported to ONNX, OpenVINO IR FP16 and CoreML at 320 and 640; `-int8` NNCF INT8 | Mirror `objectDetection/yolov9` |
158
- | `ssd-mobilenet-v2-coco-edgetpu`, `efficientdet-lite0-edgetpu` | Google Coral `test_data` | Apache-2.0 / Apache-2.0 | COCO | none | https://github.com/google-coral/test_data |
159
- | `ssdlite-mobiledet-coco-edgetpu` (selectable, not the default) | Google Coral `test_data`, `ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite` (sha256 `b69e508e…434a2e`); MobileDets (Xiong et al., CVPR 2021) trained with the TensorFlow Object Detection API, https://github.com/tensorflow/models/tree/master/research/object_detection | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`; https://github.com/google-coral/test_data/blob/master/LICENSE) | COCO 2017 (annotations CC BY 4.0, images under Flickr terms) | none: mirrored byte for byte, with the CPU build and `coco_labels.txt` beside it (`scripts/build-ssdlite-mobiledet-model.py`) | Mirror `objectDetection/ssdlite-mobiledet` |
126
+ | `yolo26n` (default), `yolo26s`, `yolo26m`, `yolo26l`, `yolo26x` (hidden), `yolo26n-fp16` (hidden), `yolo26n-int8`, `yolo26s-fp16` (hidden), `yolo26s-int8`, `yolo26m-fp16` (hidden), `yolo26m-int8`, `yolo26l-fp16` (hidden), `yolo26l-int8`, `yolo26n-320`, `yolo26n-320-int8`, `yolo26n-256`, `yolo26n-256-int8`, `yolo26s-320`, `yolo26s-320-int8`, `yolo26s-256`, `yolo26s-256-int8`, `yolo26m-320`, `yolo26m-320-int8`, `yolo26m-256`, `yolo26m-256-int8`, `yolo26l-320`, `yolo26l-320-int8`, `yolo26l-256`, `yolo26l-256-int8`, `yolo26x-fp16` (hidden), `yolo26x-int8` (hidden) | [Ultralytics](https://github.com/ultralytics/ultralytics) | AGPL-3.0 / AGPL-3.0 (`AGPL-3.0.txt`) | COCO 2017: annotations CC-BY-4.0; images under their Flickr owners' terms | exported to ONNX, OpenVINO IR and CoreML (scripts/build-camstack-models.py); OpenVINO FP16 export; exported to OpenVINO IR, then OpenVINO NNCF INT8 post-training quantisation; re-exported at 320×320 to ONNX, OpenVINO IR and CoreML; re-exported at 320×320 to OpenVINO IR; OpenVINO NNCF INT8 post-training quantisation; re-exported at 256×256 to ONNX, OpenVINO IR and CoreML; re-exported at 256×256 to OpenVINO IR; OpenVINO NNCF INT8 post-training quantisation | mirror `objectDetection/yolo26` |
127
+ | `ssd-mobilenet-v2-coco-edgetpu` (default), `efficientdet-lite0-edgetpu` | [Google Coral test_data](https://github.com/google-coral/test_data) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | COCO 2017: annotations CC-BY-4.0; images under their Flickr owners' terms | none | https://github.com/google-coral/test_data |
128
+ | `ssdlite-mobiledet-coco-edgetpu` | [Google Coral test_data](https://github.com/google-coral/test_data) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | COCO 2017: annotations CC-BY-4.0; images under their Flickr owners' terms | none: ssdlite_mobiledet_coco_qat_postprocess_edgetpu.tflite mirrored byte for byte (sha256 b69e508e…434a2e), with the CPU build and coco_labels.txt beside it (scripts/build-ssdlite-mobiledet-model.py) | mirror `objectDetection/ssdlite-mobiledet` |
129
+ | `yolov9t-320`, `yolov9t-320-int8`, `yolov9t-640`, `yolov9t-640-int8`, `yolov9s-320`, `yolov9s-320-int8`, `yolov9s-640`, `yolov9s-640-int8`, `yolov9m-320`, `yolov9m-320-int8`, `yolov9m-640`, `yolov9m-640-int8`, `yolov9c-320`, `yolov9c-320-int8`, `yolov9c-640`, `yolov9c-640-int8` | [Ultralytics](https://github.com/ultralytics/ultralytics) | AGPL-3.0 / AGPL-3.0 (`AGPL-3.0.txt`) | COCO 2017: annotations CC-BY-4.0; images under their Flickr owners' terms | exported at 320×320 to ONNX, OpenVINO IR FP16 and CoreML; exported at 320×320 to OpenVINO IR; OpenVINO NNCF INT8 post-training quantisation; exported at 640×640 to ONNX, OpenVINO IR FP16 and CoreML; exported at 640×640 to OpenVINO IR; OpenVINO NNCF INT8 post-training quantisation | mirror `objectDetection/yolov9` |
160
130
 
161
131
  ### Package detection
162
132
 
163
133
  | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
164
134
  | --- | --- | --- | --- | --- | --- |
165
- | `rfdetr-package` | Roboflow RF-DETR-M | Apache-2.0 / Apache-2.0 | fine-tuning set not recorded (unverified) | fine-tuned to 2 classes at 576; exported to ONNX, OpenVINO IR and CoreML; training checkpoint `.pth` also published | Mirror `packageDetection/rfdetr-package` |
166
- | `yolov8n-package` | Ultralytics YOLOv8n | AGPL-3.0 / AGPL-3.0 | most likely Roboflow Universe `package-at-front-door` (unverified) | fine-tuned by CamStack with Ultralytics; exported to ONNX, OpenVINO IR and CoreML | Mirror `packageDetection/yolov8-package` |
135
+ | `yolov8n-package` | [Ultralytics](https://github.com/ultralytics/ultralytics) | AGPL-3.0 / AGPL-3.0 (`AGPL-3.0.txt`) | Roboflow Universe package-at-front-door (most likely): UNVERIFIED | fine-tuned by CamStack with Ultralytics; exported to ONNX, OpenVINO IR and CoreML | mirror `packageDetection/yolov8-package` |
136
+ | `rfdetr-package` (default) | [Roboflow RF-DETR](https://github.com/roboflow/rf-detr) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | parcel fine-tuning set (not recorded): UNVERIFIED | RF-DETR-M fine-tuned to 2 classes at 576; exported to ONNX, OpenVINO IR and CoreML; training checkpoint .pth also published | mirror `packageDetection/rfdetr-package` |
167
137
 
168
138
  ### Face detection
169
139
 
170
140
  | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
171
141
  | --- | --- | --- | --- | --- | --- |
172
- | `scrfd-2.5g` | InsightFace SCRFD 2.5G (bnkps), via the ONNX re-upload `RuteNL/SCRFD-face-detection-ONNX` | MIT / **InsightFace: non-commercial research only** | WIDER FACE (research-oriented terms) | converted to OpenVINO IR and CoreML FP16 | Mirror `faceDetection/scrfd` |
173
- | `yunet-2023mar` (face-detection default since 2026-09-26) | OpenCV Zoo YuNet 2023mar, `face_detection_yunet_2023mar.onnx` (fp32), https://github.com/opencv/opencv_zoo/tree/main/models/face_detection_yunet | BSD-3-Clause (training code, https://github.com/ShiqiYu/libfacedetection.train; `BSD-3-Clause.txt`) / MIT, Copyright (c) 2020 Shiqi Yu (opencv_zoo; `MIT-yunet-reference.txt`; https://github.com/opencv/opencv_zoo/blob/main/models/face_detection_yunet/LICENSE) | WIDER FACE (images CC BY-NC-ND) | input contract baked into the graph: the pool's RGB /255 becomes the upstream BGR 0..255 (`Mul(255)` plus a channel `Gather`); internal tensor names cleared in the OpenVINO IR; ONNX fp32, OpenVINO IR fp32, CoreML fp16 (`scripts/build-yunet-model.py`) | Mirror `faceDetection/yunet` |
174
- | `scrypted-yolov9t-face` (retired from the catalog, D643; nothing downloads it) | Scrypted `plugin-models` (YOLOv9t ReLU face) | repository tagged MIT; YOLOv9 architecture GPL-3.0 upstream / **Unknown** per model | unknown | OpenVINO IR converted by CamStack | its OpenVINO IR is still on mirror `faceDetection/scrypted-yolov9-face` |
175
- | `ssd-mobilenet-v2-face-edgetpu` (hidden) | Google Coral `test_data` | Apache-2.0 / Apache-2.0 | — | none | https://github.com/google-coral/test_data |
142
+ | `scrfd-2.5g` | [InsightFace SCRFD](https://github.com/deepinsight/insightface/tree/master/detection/scrfd) | MIT / **LicenseRef-InsightFace-NonCommercial-Research** (`InsightFace-terms.txt`) | WIDER FACE: research-oriented terms; images CC BY-NC-ND | obtained via RuteNL/SCRFD-face-detection-ONNX; converted to OpenVINO IR and CoreML FP16 | mirror `faceDetection/scrfd` |
143
+ | `yunet-2023mar` (default) | [OpenCV Zoo YuNet](https://github.com/opencv/opencv_zoo/tree/main/models/face_detection_yunet) | BSD-3-Clause (`BSD-3-Clause.txt`) / MIT (`MIT-yunet-reference.txt`) | WIDER FACE: research-oriented terms; images CC BY-NC-ND | input contract baked into the graph (the pool RGB /255 becomes the upstream BGR 0..255: Mul(255) plus a channel Gather); internal tensor names cleared in the OpenVINO IR; ONNX fp32, OpenVINO IR fp32, CoreML fp16 (scripts/build-yunet-model.py) | mirror `faceDetection/yunet` |
144
+ | `ssd-mobilenet-v2-face-edgetpu` (hidden) | [Google Coral test_data](https://github.com/google-coral/test_data) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | — | none | https://github.com/google-coral/test_data |
176
145
 
177
146
  ### Face recognition
178
147
 
179
148
  | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
180
149
  | --- | --- | --- | --- | --- | --- |
181
- | `arcface-r100` (a ResNet34) | re-upload `onnx-community/arcface-onnx` (itself pointing at `garavv/arcface-onnx`); original author not stated | **Unknown** / **Unknown** | not stated | converted to OpenVINO IR and CoreML FP16 | Mirror `faceRecognition/arcface` |
182
- | `auraface-r100` | fal.ai AuraFace v1 (`glintr100.onnx` only) | Apache-2.0 / Apache-2.0 | stated upstream as commercially and publicly available sources | input scaling `y = 2x - 1` baked ahead of the first Conv (`scripts/build-auraface-model.py`); converted to OpenVINO IR and CoreML FP16 | Mirror `faceRecognition/auraface` |
183
- | `inception-resnet-v1` | Scrypted `plugin-models` | repository tagged MIT / **Unknown** per model | not stated | OpenVINO IR converted by CamStack | ONNX and CoreML: https://huggingface.co/scrypted/plugin-models · OpenVINO: mirror `faceRecognition/inception-resnet-v1` |
150
+ | `arcface-r100` | [onnx-community/arcface-onnx (re-upload of garavv/arcface-onnx)](https://huggingface.co/onnx-community/arcface-onnx) | — / **Unknown** | — | converted to OpenVINO IR and CoreML FP16 | mirror `faceRecognition/arcface` |
151
+ | `auraface-r100` (default) | [fal.ai AuraFace v1 (glintr100.onnx only)](https://huggingface.co/fal/AuraFace-v1) | — / Apache-2.0 (`Apache-2.0.txt`) | — | input scaling y = 2x - 1 baked ahead of the first Conv (scripts/build-auraface-model.py); converted to OpenVINO IR and CoreML FP16 | mirror `faceRecognition/auraface` |
152
+ | `inception-resnet-v1` | [Scrypted plugin-models (repository tagged MIT, no per-model terms)](https://huggingface.co/scrypted/plugin-models) | — / **Unknown** | — | ONNX and CoreML fetched from scrypted/plugin-models; OpenVINO IR converted and re-hosted by CamStack | mirror `faceRecognition/inception-resnet-v1` · https://huggingface.co/scrypted/plugin-models |
184
153
 
185
- ### Licence plate detection and OCR
154
+ ### Licence plate detection
186
155
 
187
156
  | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
188
157
  | --- | --- | --- | --- | --- | --- |
189
- | `yolov8n-plate` | Ultralytics YOLOv8n fine-tuned for plates by a third party (trained 2023-12-05 per its metadata) | AGPL-3.0 / AGPL-3.0 | **unknown** | converted to OpenVINO IR, CoreML and TFLite fp32 (`tflite/camstack-yolov8n-plate_float32.tflite`, mirrored but not referenced by the catalog) | Mirror `plateDetection/yolov8-plate` |
190
- | `cct-s-v2-global` | `ankandrew/fast-plate-ocr` release model | MIT / MIT | private, not released upstream | input head removed (recorded in the ONNX `doc_string`); converted to OpenVINO IR and CoreML | Mirror `plateRecognition/cct-s-v2-global` |
191
- | `vgg-english-g2` | JaidedAI EasyOCR, via Scrypted `plugin-models` | Apache-2.0 / Apache-2.0 | — | OpenVINO IR converted by CamStack | ONNX and CoreML: https://huggingface.co/scrypted/plugin-models · OpenVINO: mirror `plateRecognition/vgg_english_g2` |
158
+ | `yolov8n-plate` (default) | [Ultralytics](https://github.com/ultralytics/ultralytics) | AGPL-3.0 / AGPL-3.0 (`AGPL-3.0.txt`) | unidentified plate dataset (third-party model, trained 2023-12-05 per its ONNX metadata): UNKNOWN | converted to OpenVINO IR and CoreML | mirror `plateDetection/yolov8-plate` |
192
159
 
193
- ### Classifiers
160
+ ### Licence plate reading
194
161
 
195
162
  | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
196
163
  | --- | --- | --- | --- | --- | --- |
197
- | `animal-classifier` | timm EfficientNet-Lite0 | Apache-2.0 / Apache-2.0 | Open Images V7 animal subset (annotations CC BY 4.0, © Google LLC) | fine-tuned by CamStack (8 classes); exported to ONNX, OpenVINO IR and CoreML | Mirror `animalClassification/animal-classifier` |
198
- | `animals-10` (hidden, pending removal) | origin not identified | **Unknown** / **Unknown** | unknown | converted to ONNX, OpenVINO IR and CoreML | Mirror `animalClassification/animals-10` |
199
- | `bird-classifier` | Google AIY Vision `birds_V1` | Apache-2.0 / Apache-2.0 | — | converted from TensorFlow with tf2onnx; OpenVINO IR and CoreML derived from it | Mirror `animalClassification/bird-classifier` |
200
- | `bird-classifier-aiy-edgetpu` (hidden) | Google Coral `test_data` | Apache-2.0 / Apache-2.0 | — | none | https://github.com/google-coral/test_data |
201
- | `bird-nabirds-404` (hidden, pending removal) | ResNet50 trained on NABirds (origin not recorded) | **Unknown** / NABirds: no products without Cornell Lab permission | NABirds (Cornell Lab of Ornithology) | converted to ONNX, OpenVINO IR and CoreML | Mirror `animalClassification/bird-nabirds` |
202
- | `vehicle-type-v1` | torchvision MobileNetV3-Large | BSD-3-Clause / **CC BY-NC 4.0** (from its data) | DrBimmer `vehicle-classification`, CC BY-NC 4.0 | fine-tuned by CamStack (8 classes); exported to ONNX, OpenVINO IR and CoreML | Mirror `vehicleClassification/vehicle-type-v1` |
203
- | `vehicle-type-efficientnet` (hidden, pending removal) | trained on VMMRdb (origin not recorded) | **Unknown** / VMMRdb terms unverified | VMMRdb | converted to ONNX, OpenVINO IR and CoreML | Mirror `vehicleClassification/efficientnet` |
164
+ | `cct-s-v2-global` (default) | [ankandrew/fast-plate-ocr](https://github.com/ankandrew/fast-plate-ocr) | MIT / MIT (`MIT-fast-plate-ocr.txt`) | fast-plate-ocr training set: private, not released upstream | input head removed (recorded in the ONNX doc_string); converted to OpenVINO IR and CoreML | mirror `plateRecognition/cct-s-v2-global` |
165
+ | `vgg-english-g2` | [JaidedAI EasyOCR (via Scrypted plugin-models)](https://github.com/JaidedAI/EasyOCR) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | — | ONNX and CoreML fetched from scrypted/plugin-models; OpenVINO IR converted and re-hosted by CamStack | mirror `plateRecognition/vgg_english_g2` · https://huggingface.co/scrypted/plugin-models |
204
166
 
205
- ### Semantic search (CLIP)
167
+ ### Animal classifier
206
168
 
207
169
  | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
208
170
  | --- | --- | --- | --- | --- | --- |
209
- | `mobileclip-s1`, `mobileclip-s2` (image) | Apple `ml-mobileclip` | MIT / **Apple Machine Learning Research Model License** | per Apple | Model Derivative: converted to OpenVINO IR and CoreML FP16 | Mirror `clip/mobileclip-s1`, `clip/mobileclip-s2` |
210
- | `mobileclip-s1-text`, `mobileclip-s2-text` | Apple `ml-mobileclip`, with the CLIP tokenizer | MIT / **Apple Machine Learning Research Model License** | per Apple | Model Derivative: quantised to INT8 ONNX and converted to OpenVINO IR | Mirror `clip/mobileclip-s1`, `clip/mobileclip-s2` |
211
- | `siglip2-b16-224` (image) | Google SigLIP 2 base patch16-224 (`google/siglip2-base-patch16-224`) | Apache-2.0 / Apache-2.0 | WebLI (Google internal, not released) | input scaling `y = 2x - 1` baked ahead of the patch embedding; converted to OpenVINO IR and CoreML FP16 (an FP32 ONNX is hosted as the verification reference) (`scripts/build-siglip2-model.py`) | Mirror `clip/siglip2` |
212
- | `siglip2-b16-224-text` | Google SigLIP 2 base patch16-224, with its Gemma tokenizer | Apache-2.0 / Apache-2.0 | WebLI (Google internal, not released) | input sliced to the model's 64 positions in the graph; ONNX weights FP16, OpenVINO IR and CoreML FP16; a `Lowercase` normalizer prepended to the tokenizer | Mirror `clip/siglip2` |
171
+ | `animal-classifier` (default) | [timm EfficientNet-Lite0, fine-tuned by CamStack](https://github.com/huggingface/pytorch-image-models) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | Open Images V7: annotations CC-BY-4.0 (Google LLC); images listed as CC-BY-2.0, no warranty | fine-tuned by CamStack on the Open Images V7 animal subset (8 classes); exported to ONNX, OpenVINO IR and CoreML | mirror `animalClassification/animal-classifier` |
172
+
173
+ ### Bird classifier
174
+
175
+ | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
176
+ | --- | --- | --- | --- | --- | --- |
177
+ | `bird-classifier` (default) | [Google AIY Vision birds_V1](https://github.com/google-coral/test_data) | — / Apache-2.0 (`Apache-2.0.txt`) | — | converted from TensorFlow with tf2onnx; OpenVINO IR and CoreML derived from it | mirror `animalClassification/bird-classifier` |
178
+ | `bird-classifier-aiy-edgetpu` (hidden) | [Google Coral test_data](https://github.com/google-coral/test_data) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | — | none | https://github.com/google-coral/test_data |
179
+
180
+ ### Vehicle classifier
181
+
182
+ | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
183
+ | --- | --- | --- | --- | --- | --- |
184
+ | `vehicle-type-v1` (default) | [torchvision MobileNetV3-Large, fine-tuned by CamStack](https://github.com/pytorch/vision) | BSD-3-Clause (`BSD-3-Clause.txt`) / **CC-BY-NC-4.0** (`CC-BY-NC-4.0.txt`) | DrBimmer/vehicle-classification: CC-BY-NC-4.0 — treated as binding the trained weights (conservative reading) | fine-tuned by CamStack (8 classes); exported to ONNX, OpenVINO IR and CoreML | mirror `vehicleClassification/vehicle-type-v1` |
185
+
186
+ ### Semantic search, image encoders (CLIP)
187
+
188
+ | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
189
+ | --- | --- | --- | --- | --- | --- |
190
+ | `mobileclip-s1` (default) | [Apple ml-mobileclip](https://github.com/apple/ml-mobileclip) | MIT / **LicenseRef-Apple-AMLR** (`Apple-AMLR.txt`) | — | model derivative: vision encoders converted to OpenVINO IR and CoreML FP16 | mirror `clip/mobileclip-s1` |
191
+ | `mobileclip-s2` | [Apple ml-mobileclip](https://github.com/apple/ml-mobileclip) | MIT / **LicenseRef-Apple-AMLR** (`Apple-AMLR.txt`) | — | model derivative: vision encoders converted to OpenVINO IR and CoreML FP16 | mirror `clip/mobileclip-s2` |
192
+ | `siglip2-b16-224` | [Google SigLIP 2 (google/siglip2-base-patch16-224)](https://huggingface.co/google/siglip2-base-patch16-224) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | WebLI: Google internal, not released | input scaling y = 2x - 1 baked ahead of the patch embedding; converted to OpenVINO IR and CoreML FP16, an FP32 ONNX hosted as the verification reference (scripts/build-siglip2-model.py) | mirror `clip/siglip2` |
193
+
194
+ ### Semantic search, text encoders (CLIP)
195
+
196
+ | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
197
+ | --- | --- | --- | --- | --- | --- |
198
+ | `mobileclip-s1-text` | [Apple ml-mobileclip](https://github.com/apple/ml-mobileclip) | MIT / **LicenseRef-Apple-AMLR** (`Apple-AMLR.txt`) | — | model derivative: text encoders quantised to INT8 ONNX and converted to OpenVINO IR | mirror `clip/mobileclip-s1` |
199
+ | `mobileclip-s2-text` | [Apple ml-mobileclip](https://github.com/apple/ml-mobileclip) | MIT / **LicenseRef-Apple-AMLR** (`Apple-AMLR.txt`) | — | model derivative: text encoders quantised to INT8 ONNX and converted to OpenVINO IR | mirror `clip/mobileclip-s2` |
200
+ | `siglip2-b16-224-text` | [Google SigLIP 2 (google/siglip2-base-patch16-224)](https://huggingface.co/google/siglip2-base-patch16-224) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | WebLI: Google internal, not released | input sliced to the model's 64 positions in the graph; ONNX weights FP16, OpenVINO IR and CoreML FP16; a Lowercase normalizer prepended to the Gemma tokenizer (scripts/build-siglip2-model.py) | mirror `clip/siglip2` |
213
201
 
214
202
  ### Segmentation
215
203
 
216
204
  | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
217
205
  | --- | --- | --- | --- | --- | --- |
218
- | `u2netp` | `xuebinqin/U-2-Net` | Apache-2.0 / Apache-2.0 | DUTS-TR (terms not checked) | converted to ONNX, OpenVINO IR and CoreML | Mirror `segmentationRefiner/u2netp` |
219
- | `yolo26n-seg`, `yolo26s-seg`, `yolo26m-seg` | Ultralytics YOLO26-seg, COCO-pretrained | AGPL-3.0 / AGPL-3.0 | COCO 2017 | exported to ONNX, OpenVINO IR and CoreML | Mirror `segmentation/yolo26-seg` |
206
+ | `u2netp` (default) | [xuebinqin/U-2-Net](https://github.com/xuebinqin/U-2-Net) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | DUTS-TR: not checked | converted to ONNX, OpenVINO IR and CoreML | mirror `segmentationRefiner/u2netp` |
207
+
208
+ ### Instance segmentation (dormant step)
209
+
210
+ | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
211
+ | --- | --- | --- | --- | --- | --- |
212
+ | `yolo26n-seg`, `yolo26s-seg`, `yolo26m-seg` | [Ultralytics](https://github.com/ultralytics/ultralytics) | AGPL-3.0 / AGPL-3.0 (`AGPL-3.0.txt`) | COCO 2017: annotations CC-BY-4.0; images under their Flickr owners' terms | exported to ONNX, OpenVINO IR and CoreML | mirror `segmentation/yolo26-seg` |
220
213
 
221
214
  ### Audio
222
215
 
223
216
  | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
224
217
  | --- | --- | --- | --- | --- | --- |
225
- | `yamnet-onnx` | `tensorflow/models` `research/audioset/yamnet` | Apache-2.0 / Apache-2.0 | AudioSet (labels CC BY 4.0, © Google LLC) | converted from TensorFlow with tf2onnx; OpenVINO IR derived from it | Mirror `audioClassification/yamnet` |
226
- | `apple-soundanalysis` | Apple SoundAnalysis, built into macOS | under Apple's macOS licence | — | nothing downloaded | built in |
218
+ | `yamnet-onnx` (default) | [tensorflow/models research/audioset/yamnet](https://github.com/tensorflow/models/tree/master/research/audioset/yamnet) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | AudioSet ontology/labels: CC-BY-4.0 (Google LLC) | converted from TensorFlow with tf2onnx; OpenVINO IR derived from it | mirror `audioClassification/yamnet` |
219
+ | `apple-soundanalysis` (default) | [Apple SoundAnalysis (macOS built-in)](https://developer.apple.com/documentation/soundanalysis) | — / LicenseRef-Apple-macOS | — | none | built in, nothing downloaded |
227
220
 
228
- ### Language and vision-language models (AI addon, not hosted by CamStack)
221
+ ### Language and vision-language models (AI addon)
229
222
 
230
- | Catalog ids | Upstream | Code / weights | CamStack changes | Downloaded from |
231
- | --- | --- | --- | --- | --- |
232
- | `llm-qwen2.5-1.5b-instruct-q4` | Qwen2.5 1.5B Instruct | — / Apache-2.0 | none (GGUF Q4_K_M by Qwen) | https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct-GGUF |
233
- | `llm-llama3.2-3b-instruct-q4` | Meta Llama 3.2 3B Instruct | — / Llama 3.2 Community License | none by CamStack (GGUF Q4_K_M by bartowski) | https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF |
234
- | `llm-qwen3-vl-2b-instruct-q4`, `llm-qwen3-vl-4b-instruct-q4`, `llm-qwen3-vl-8b-instruct-q4` | Qwen3-VL Instruct | — / Apache-2.0 | none by CamStack (GGUF by unsloth) | https://huggingface.co/unsloth (`Qwen3-VL-{2B,4B,8B}-Instruct-GGUF`) |
235
- | `llm-qwen3.6-35b-a3b-ud-q4` | Qwen3.6 35B-A3B | — / Apache-2.0 | none by CamStack (GGUF UD-Q4_K_M by unsloth) | https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF |
223
+ | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
224
+ | --- | --- | --- | --- | --- | --- |
225
+ | `llm-qwen2.5-1.5b-instruct-q4` | [Qwen (Alibaba Cloud)](https://huggingface.co/Qwen) | — / Apache-2.0 (`Apache-2.0.txt`) | — | none (GGUF Q4_K_M published by Qwen; not re-hosted by CamStack) | https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct-GGUF |
226
+ | `llm-llama3.2-3b-instruct-q4` | [Meta Llama 3.2 (GGUF by bartowski)](https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF) | — / LicenseRef-Llama-3.2-Community (`Llama-3.2-Community.txt`) | — | Q4_K_M GGUF quantisation by bartowski (not re-hosted by CamStack) | https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF |
227
+ | `llm-qwen3-vl-2b-instruct-q4` | [Qwen3-VL (GGUF by unsloth)](https://huggingface.co/unsloth) | — / Apache-2.0 (`Apache-2.0.txt`) | — | Q4_K_M GGUF quantisation by unsloth (not re-hosted by CamStack) | https://huggingface.co/unsloth/Qwen3-VL-2B-Instruct-GGUF |
228
+ | `llm-qwen3-vl-4b-instruct-q4` | [Qwen3-VL (GGUF by unsloth)](https://huggingface.co/unsloth) | — / Apache-2.0 (`Apache-2.0.txt`) | — | Q4_K_M GGUF quantisation by unsloth (not re-hosted by CamStack) | https://huggingface.co/unsloth/Qwen3-VL-4B-Instruct-GGUF |
229
+ | `llm-qwen3-vl-8b-instruct-q4` | [Qwen3-VL (GGUF by unsloth)](https://huggingface.co/unsloth) | — / Apache-2.0 (`Apache-2.0.txt`) | — | Q4_K_M GGUF quantisation by unsloth (not re-hosted by CamStack) | https://huggingface.co/unsloth/Qwen3-VL-8B-Instruct-GGUF |
230
+ | `llm-qwen3.6-35b-a3b-ud-q4` | [Qwen3.6-35B-A3B (GGUF by unsloth)](https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF) | — / Apache-2.0 (`Apache-2.0.txt`) | — | UD-Q4_K_M GGUF quantisation by unsloth (not re-hosted by CamStack) | https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF |
231
+
232
+ ### Model Studio catalogs (object detection, imported on request)
233
+
234
+ | Catalog ids | Upstream | Code / weights | Training data | CamStack changes | Downloaded from |
235
+ | --- | --- | --- | --- | --- | --- |
236
+ | `scrypted-yolov9t-relu-coreml`, `scrypted-yolov9t-relu-onnx`, `scrypted-yolov9t-relu-test-coreml`, `scrypted-yolov9t-relu-test-onnx`, `scrypted-yolov9s-relu-coreml`, `scrypted-yolov9s-relu-onnx`, `scrypted-yolov9s-relu-test-coreml`, `scrypted-yolov9s-relu-test-onnx`, `scrypted-yolov9m-relu-coreml`, `scrypted-yolov9m-relu-onnx`, `scrypted-yolov9m-relu-test-coreml`, `scrypted-yolov9m-relu-test-onnx`, `scrypted-yolov9c-relu-coreml`, `scrypted-yolov9c-relu-onnx`, `scrypted-yolov9c-relu-test-coreml`, `scrypted-yolov9c-relu-test-onnx`, `scrypted-yolov9t-relu-openvino-fp32`, `scrypted-yolov9s-relu-openvino-fp32`, `scrypted-yolov9m-relu-openvino-fp32`, `scrypted-yolov9c-relu-openvino-fp32`, `scrypted-yolov9t-relu-openvino-int8`, `scrypted-yolov9t-relu-test-openvino-int8`, `scrypted-yolov9s-relu-openvino-int8`, `scrypted-yolov9s-relu-test-openvino-int8`, `scrypted-yolov9m-relu-openvino-int8`, `scrypted-yolov9m-relu-test-openvino-int8`, `scrypted-yolov9c-relu-openvino-int8`, `scrypted-yolov9c-relu-test-openvino-int8`, `scrypted-yolov9s-relu-sep-320-tflite-float16`, `scrypted-yolov9s-relu-sep-320-tflite-float32`, `scrypted-yolov9s-relu-sep-320-tflite-int8`, `scrypted-yolov9s-relu-sep-320-tflite-integer_quant`, `scrypted-yolov9s-relu-sep-320-tflite-full_integer_quant`, `scrypted-yolov9s-relu-sep-320-tflite-edgetpu` | [Scrypted plugin-models (repository tagged MIT, no per-model terms)](https://huggingface.co/scrypted/plugin-models) | GPL-3.0 (`GPL-3.0.txt`) / **Unknown** | not stated by Scrypted: UNKNOWN | none: downloaded as published, at a pinned revision | https://huggingface.co/scrypted/plugin-models |
237
+ | `frigate-mobiledet-edgetpu` | [Google Coral test_data](https://github.com/google-coral/test_data) | Apache-2.0 / Apache-2.0 (`Apache-2.0.txt`) | COCO 2017: annotations CC-BY-4.0; images under their Flickr owners' terms | none | https://github.com/google-coral/test_data |
236
238
 
237
239
  ### Your own models
238
240
 
239
- A model you import through Model Studio (uploaded, converted, or pulled from
240
- Frigate+ or Scrypted) keeps whatever licence its author published. CamStack
241
- does not change it and does not record it.
241
+ The Scrypted and Frigate catalogs that Model Studio offers are listed above. A
242
+ model you upload or convert yourself, or pull from your own Frigate+ account,
243
+ keeps whatever licence its author published. CamStack does not change it and
244
+ does not record it.
package/dist/addon.js CHANGED
@@ -5525,7 +5525,7 @@ function number(params) {
5525
5525
  return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
5526
5526
  }
5527
5527
  //#endregion
5528
- //#region ../types/dist/sleep-BXv0ZcRa.mjs
5528
+ //#region ../types/dist/sleep-DC-wdyeS.mjs
5529
5529
  /**
5530
5530
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5531
5531
  * window to float samples (D455).
@@ -9771,6 +9771,48 @@ var ModelProviderIdSchema = _enum([
9771
9771
  "scrypted",
9772
9772
  "custom"
9773
9773
  ]);
9774
+ /**
9775
+ * The licence of a model, as a record rather than a bare SPDX string: a
9776
+ * permissive CODE licence routinely sits on top of restrictive WEIGHTS or
9777
+ * DATA, and the obligations (attribution, modification notices, source offers)
9778
+ * are per upstream. A persisted custom-model row written when this field was a
9779
+ * string still parses — the string is lifted into `{ weights }`.
9780
+ *
9781
+ * Every licence surface (the admin "Models and licenses" page,
9782
+ * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
9783
+ * these records by `scripts/gen-model-licenses.ts` (D661).
9784
+ */
9785
+ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
9786
+ /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
9787
+ weights: string().min(1),
9788
+ /** SPDX id of the upstream code that defines / trained the network. */
9789
+ code: string().min(1).optional(),
9790
+ /** Training data whose terms add obligations (attribution, non-commercial). */
9791
+ data: object({
9792
+ name: string().min(1),
9793
+ terms: string().min(1),
9794
+ url: string().url().optional()
9795
+ }).optional(),
9796
+ /** The project the weights come from. Required on built-in entries (guard). */
9797
+ upstream: object({
9798
+ name: string().min(1),
9799
+ url: string().url()
9800
+ }).optional(),
9801
+ /** Where the licence text governing the weights is published. */
9802
+ url: string().url().optional(),
9803
+ /** Attribution the licence REQUIRES, verbatim. */
9804
+ attribution: string().min(1).optional(),
9805
+ /** What CamStack changed. Required when `hosting` is `camstack-hf` (guard). */
9806
+ modifications: string().min(1).optional(),
9807
+ /** Who serves the file a node downloads. */
9808
+ hosting: _enum([
9809
+ "camstack-hf",
9810
+ "third-party",
9811
+ "built-in"
9812
+ ]).optional(),
9813
+ /** True when the weights or their data forbid commercial use. */
9814
+ nonCommercial: boolean().optional()
9815
+ }));
9774
9816
  var ModelCatalogEntrySchema = object({
9775
9817
  id: string(),
9776
9818
  name: string(),
@@ -9859,11 +9901,11 @@ var ModelCatalogEntrySchema = object({
9859
9901
  p95LatencyMs: record(string(), number$1()).optional()
9860
9902
  }).optional(),
9861
9903
  /**
9862
- * SPDX-ish license id of the model weights (e.g. `AGPL-3.0` for Ultralytics
9863
- * YOLO26, `GPL-3.0` for YOLOv9, `Apache-2.0` for D-FINE/RF-DETR). Matters for
9864
- * the retraining addon and any future commercial distribution.
9904
+ * The model's licence record — see {@link ModelLicenseSchema}. Optional in
9905
+ * the schema (a custom model's author may state none); REQUIRED and complete
9906
+ * on every built-in catalog entry (`scripts/check-catalog-licence.ts`).
9865
9907
  */
9866
- license: string().optional(),
9908
+ license: ModelLicenseSchema.optional(),
9867
9909
  /**
9868
9910
  * Variant-selector grouping. The UI groups models by `family` + `tier` and
9869
9911
  * offers `precision` / `optimization` as variant axes WITHIN a tier — so all
@@ -11172,12 +11214,32 @@ var AudioClassificationLabelSchema = object({
11172
11214
  originalClass: string().optional(),
11173
11215
  score: number$1()
11174
11216
  });
11217
+ /**
11218
+ * Did the classifier RUN on this window? (D660)
11219
+ *
11220
+ * `classified` with no labels means the model heard nothing above the
11221
+ * camera's floor. `not-classified` means nobody listened — and until D660 the
11222
+ * two were the same shape (`classification` absent), so a window the global
11223
+ * busy gate threw away read downstream exactly like a quiet one (D393).
11224
+ */
11225
+ var AudioClassifyOutcomeSchema = discriminatedUnion("state", [object({ state: literal("classified") }), object({
11226
+ state: literal("not-classified"),
11227
+ reason: _enum([
11228
+ "superseded",
11229
+ "error",
11230
+ "timeout",
11231
+ "disposed"
11232
+ ])
11233
+ })]);
11175
11234
  var AudioAnalysisResultSchema = object({
11176
11235
  level: AudioLevelSchema,
11236
+ /** Labels at or above the camera's floor. Absent = none — read `classifyOutcome` to know whether the model ran at all. */
11177
11237
  classification: object({
11178
11238
  labels: array(AudioClassificationLabelSchema).readonly(),
11179
11239
  inferenceMs: number$1()
11180
11240
  }).optional(),
11241
+ /** Whether the classifier ran on this window (D660). */
11242
+ classifyOutcome: AudioClassifyOutcomeSchema,
11181
11243
  timestamp: number$1()
11182
11244
  });
11183
11245
  var AudioAnalysisSettingsSchema = object({
@@ -14114,8 +14176,22 @@ var LinkedDeviceSchema = object({
14114
14176
  * The `linked-devices` extension slot's editable value (D648): the operator's
14115
14177
  * pick list, exactly what `_linkedDeviceIds` persists. Tree children are NOT
14116
14178
  * in it — they are always linked and are not a pick.
14117
- */
14118
- var LinkedDevicesSlotValueSchema = object({ deviceIds: array(number$1().int().positive()) });
14179
+ *
14180
+ * `trackedDeviceIds` (D655) is the tracked-event opt-in, exactly what
14181
+ * `_linkedDeviceTrackedIds` persists: which linked devices materialize a
14182
+ * synthetic tracked event on the camera. A read always carries it AS STORED
14183
+ * (an absent key reads as `[]`, which is what the resolver makes of it —
14184
+ * NONE). On a write it is optional: absent leaves the opt-in untouched, so a
14185
+ * card built before D655 cannot erase it by saving the pick list. A present
14186
+ * list REPLACES the opt-in; each id must be a pick, a device the camera links
14187
+ * by structure (the row's `impliedSources`: tree children, a picked
14188
+ * container's child) or already stored — so what was read can always be
14189
+ * written back unchanged, and a NEW opt-in outside the linked set is refused.
14190
+ */
14191
+ var LinkedDevicesSlotValueSchema = object({
14192
+ deviceIds: array(number$1().int().positive()),
14193
+ trackedDeviceIds: array(number$1().int().positive()).optional()
14194
+ });
14119
14195
  DeviceType.Camera;
14120
14196
  /** One camera's resolved linked set, tagged with the camera it belongs to.
14121
14197
  * The batch answer needs the tag; the single-device answer already has it
@@ -20554,6 +20630,13 @@ var AudioEventSchema = object({
20554
20630
  originalClass: string().optional(),
20555
20631
  score: number$1()
20556
20632
  }).optional(),
20633
+ /**
20634
+ * Whether the classifier RAN on the window behind this row (D660). Absent
20635
+ * on rows written before D660 — unknown, NOT classified: until then a
20636
+ * window the analyzer's busy gate threw away was stored exactly like one
20637
+ * that heard nothing above the floor.
20638
+ */
20639
+ classifyOutcome: AudioClassifyOutcomeSchema.optional(),
20557
20640
  /** Populated by B5 (recording playback URL for this event). */
20558
20641
  mediaUrl: string().optional()
20559
20642
  });
@@ -22145,7 +22228,14 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
22145
22228
  height: number$1()
22146
22229
  }), { kind: "mutation" }), method(object({
22147
22230
  stepId: string(),
22148
- frameId: number$1().int()
22231
+ frameId: number$1().int(),
22232
+ /**
22233
+ * The model to time — REQUIRED (D658). Without it the pool answered the
22234
+ * step's ACTIVE variant (the first loaded after boot), so a benchmark
22235
+ * of model B silently timed model A. Callers pass the `rootModelId`
22236
+ * their warmup `runPipeline` reported: the model that actually ran.
22237
+ */
22238
+ modelId: string().min(1)
22149
22239
  }), record(string(), unknown()), { kind: "mutation" }), method(object({ frameId: number$1().int() }), _void(), { kind: "mutation" }), method(object({ deviceKey: string().optional() }), EffectiveTuningSchema), method(_void(), array(object({
22150
22240
  engineKey: string(),
22151
22241
  engine: PipelineEngineChoiceSchema,
@@ -26107,7 +26197,17 @@ var ExtensionSlotRowSchema = discriminatedUnion("state", [object({
26107
26197
  projects: string().nullable(),
26108
26198
  activation: ExtensionSlotActivationSchema.nullable(),
26109
26199
  value: ExtensionSlotValueSchema,
26110
- sources: array(ExtensionSlotSourceSchema)
26200
+ sources: array(ExtensionSlotSourceSchema),
26201
+ /**
26202
+ * Devices the owner links to the host ON ITS OWN, by structure, and that
26203
+ * are therefore not in `value` (D655): a camera's device-tree children, and
26204
+ * the child a picked container stands for (D356 — a container is never a
26205
+ * pick, its children are). Read-only; the editor shows them and may offer
26206
+ * per-device options on them (the linked-devices tracked-event opt-in).
26207
+ * Absent when the owner links nothing beyond the picks, and from an owner
26208
+ * older than D655.
26209
+ */
26210
+ impliedSources: array(ExtensionSlotSourceSchema).optional()
26111
26211
  }), object({
26112
26212
  state: literal("unreachable"),
26113
26213
  addonId: string(),
@@ -37597,12 +37697,6 @@ Object.freeze({
37597
37697
  addonId: null,
37598
37698
  access: "create"
37599
37699
  },
37600
- "deviceManager.applyDeviceSettingsPatch": {
37601
- capName: "device-manager",
37602
- capScope: "system",
37603
- addonId: null,
37604
- access: "create"
37605
- },
37606
37700
  "deviceManager.applyInitialMeta": {
37607
37701
  capName: "device-manager",
37608
37702
  capScope: "system",
@@ -37705,12 +37799,6 @@ Object.freeze({
37705
37799
  addonId: null,
37706
37800
  access: "view"
37707
37801
  },
37708
- "deviceManager.getDeviceLiveContribution": {
37709
- capName: "device-manager",
37710
- capScope: "system",
37711
- addonId: null,
37712
- access: "view"
37713
- },
37714
37802
  "deviceManager.getDeviceLiveInfoAggregate": {
37715
37803
  capName: "device-manager",
37716
37804
  capScope: "system",
@@ -37723,12 +37811,6 @@ Object.freeze({
37723
37811
  addonId: null,
37724
37812
  access: "view"
37725
37813
  },
37726
- "deviceManager.getDeviceSettingsContribution": {
37727
- capName: "device-manager",
37728
- capScope: "system",
37729
- addonId: null,
37730
- access: "view"
37731
- },
37732
37814
  "deviceManager.getDeviceStatusAggregate": {
37733
37815
  capName: "device-manager",
37734
37816
  capScope: "system",
@@ -38233,24 +38315,6 @@ Object.freeze({
38233
38315
  addonId: null,
38234
38316
  access: "view"
38235
38317
  },
38236
- "doorbell.applyDeviceSettingsPatch": {
38237
- capName: "doorbell",
38238
- capScope: "device",
38239
- addonId: null,
38240
- access: "create"
38241
- },
38242
- "doorbell.getDeviceLiveContribution": {
38243
- capName: "doorbell",
38244
- capScope: "device",
38245
- addonId: null,
38246
- access: "view"
38247
- },
38248
- "doorbell.getDeviceSettingsContribution": {
38249
- capName: "doorbell",
38250
- capScope: "device",
38251
- addonId: null,
38252
- access: "view"
38253
- },
38254
38318
  "doorbell.getStatus": {
38255
38319
  capName: "doorbell",
38256
38320
  capScope: "device",
@@ -83817,6 +83881,53 @@ function createLlmProvider(deps) {
83817
83881
  };
83818
83882
  }
83819
83883
  //#endregion
83884
+ //#region src/runtime/llm-model-licenses.ts
83885
+ var QWEN_ATTRIBUTION = "Qwen models © Alibaba Cloud, Apache-2.0.";
83886
+ var QWEN_APACHE = {
83887
+ weights: "Apache-2.0",
83888
+ upstream: {
83889
+ name: "Qwen (Alibaba Cloud)",
83890
+ url: "https://huggingface.co/Qwen"
83891
+ },
83892
+ url: "https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct-GGUF",
83893
+ attribution: QWEN_ATTRIBUTION,
83894
+ modifications: "none (GGUF Q4_K_M published by Qwen; not re-hosted by CamStack)",
83895
+ hosting: "third-party"
83896
+ };
83897
+ var LLAMA_32_COMMUNITY = {
83898
+ weights: "LicenseRef-Llama-3.2-Community",
83899
+ upstream: {
83900
+ name: "Meta Llama 3.2 (GGUF by bartowski)",
83901
+ url: "https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF"
83902
+ },
83903
+ url: "https://github.com/meta-llama/llama-models/blob/main/models/llama3_2/LICENSE",
83904
+ attribution: "Built with Llama. Llama 3.2 is licensed under the Llama 3.2 Community License, Copyright © Meta Platforms, Inc. All Rights Reserved.",
83905
+ modifications: "Q4_K_M GGUF quantisation by bartowski (not re-hosted by CamStack)",
83906
+ hosting: "third-party"
83907
+ };
83908
+ var QWEN_VL_APACHE = {
83909
+ weights: "Apache-2.0",
83910
+ upstream: {
83911
+ name: "Qwen3-VL (GGUF by unsloth)",
83912
+ url: "https://huggingface.co/unsloth"
83913
+ },
83914
+ url: "https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct",
83915
+ attribution: QWEN_ATTRIBUTION,
83916
+ modifications: "Q4_K_M GGUF quantisation by unsloth (not re-hosted by CamStack)",
83917
+ hosting: "third-party"
83918
+ };
83919
+ var QWEN36_APACHE = {
83920
+ weights: "Apache-2.0",
83921
+ upstream: {
83922
+ name: "Qwen3.6-35B-A3B (GGUF by unsloth)",
83923
+ url: "https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF"
83924
+ },
83925
+ url: "https://huggingface.co/Qwen/Qwen3.6-35B-A3B/blob/main/LICENSE",
83926
+ attribution: QWEN_ATTRIBUTION,
83927
+ modifications: "UD-Q4_K_M GGUF quantisation by unsloth (not re-hosted by CamStack)",
83928
+ hosting: "third-party"
83929
+ };
83930
+ //#endregion
83820
83931
  //#region src/runtime/llm-model-catalog.ts
83821
83932
  /**
83822
83933
  * Curated managed-model catalog (operator decision #4). Each entry carries BOTH
@@ -83847,7 +83958,7 @@ var GIB = 1024 * 1024 * 1024;
83847
83958
  function mb(bytes) {
83848
83959
  return Math.round(bytes / (1024 * 1024));
83849
83960
  }
83850
- function textEntry(meta) {
83961
+ function textEntry(meta, license) {
83851
83962
  return {
83852
83963
  meta,
83853
83964
  entry: {
@@ -83862,7 +83973,8 @@ function textEntry(meta) {
83862
83973
  width: 0,
83863
83974
  height: 0
83864
83975
  },
83865
- labels: []
83976
+ labels: [],
83977
+ license
83866
83978
  }
83867
83979
  };
83868
83980
  }
@@ -83877,7 +83989,7 @@ var QWEN = textEntry({
83877
83989
  quantization: "Q4_K_M",
83878
83990
  minRamBytes: 2 * GIB,
83879
83991
  contextSizeDefault: 4096
83880
- });
83992
+ }, QWEN_APACHE);
83881
83993
  var LLAMA = textEntry({
83882
83994
  id: "llm-llama3.2-3b-instruct-q4",
83883
83995
  label: "Llama 3.2 3B Instruct",
@@ -83889,7 +84001,7 @@ var LLAMA = textEntry({
83889
84001
  quantization: "Q4_K_M",
83890
84002
  minRamBytes: Math.round(3.5 * GIB),
83891
84003
  contextSizeDefault: 4096
83892
- });
84004
+ }, LLAMA_32_COMMUNITY);
83893
84005
  var QWEN3VL2B_MODEL_BYTES = 1107410624;
83894
84006
  var QWEN3VL2B_MMPROJ_BYTES = 819395232;
83895
84007
  var QWEN3VL2B_BASE = "https://huggingface.co/unsloth/Qwen3-VL-2B-Instruct-GGUF/resolve/main";
@@ -83918,6 +84030,7 @@ var QWEN3VL_2B = {
83918
84030
  },
83919
84031
  entry: {
83920
84032
  id: "llm-qwen3-vl-2b-instruct-q4",
84033
+ license: QWEN_VL_APACHE,
83921
84034
  name: "Qwen3-VL 2B Instruct (vision, light)",
83922
84035
  description: "qwen3-vl · Q4_K_M · +mmproj",
83923
84036
  formats: { gguf: {
@@ -83972,6 +84085,7 @@ var QWEN3VL_4B = {
83972
84085
  },
83973
84086
  entry: {
83974
84087
  id: "llm-qwen3-vl-4b-instruct-q4",
84088
+ license: QWEN_VL_APACHE,
83975
84089
  name: "Qwen3-VL 4B Instruct (vision)",
83976
84090
  description: "qwen3-vl · Q4_K_M · +mmproj",
83977
84091
  formats: { gguf: {
@@ -84023,6 +84137,7 @@ var QWEN3VL_8B = {
84023
84137
  },
84024
84138
  entry: {
84025
84139
  id: "llm-qwen3-vl-8b-instruct-q4",
84140
+ license: QWEN_VL_APACHE,
84026
84141
  name: "Qwen3-VL 8B Instruct (vision)",
84027
84142
  description: "qwen3-vl · Q4_K_M · +mmproj",
84028
84143
  formats: { gguf: {
@@ -84068,6 +84183,7 @@ var LLM_MODEL_CATALOG = [
84068
84183
  },
84069
84184
  entry: {
84070
84185
  id: "llm-qwen3.6-35b-a3b-ud-q4",
84186
+ license: QWEN36_APACHE,
84071
84187
  name: "Qwen3.6 35B-A3B (vision)",
84072
84188
  description: "qwen3.6 · UD-Q4_K_M · +mmproj",
84073
84189
  formats: { gguf: {
package/dist/addon.mjs CHANGED
@@ -5551,7 +5551,7 @@ function number(params) {
5551
5551
  return /* @__PURE__ */ _coercedNumber(ZodNumber, params);
5552
5552
  }
5553
5553
  //#endregion
5554
- //#region ../types/dist/sleep-BXv0ZcRa.mjs
5554
+ //#region ../types/dist/sleep-DC-wdyeS.mjs
5555
5555
  /**
5556
5556
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5557
5557
  * window to float samples (D455).
@@ -9797,6 +9797,48 @@ var ModelProviderIdSchema = _enum([
9797
9797
  "scrypted",
9798
9798
  "custom"
9799
9799
  ]);
9800
+ /**
9801
+ * The licence of a model, as a record rather than a bare SPDX string: a
9802
+ * permissive CODE licence routinely sits on top of restrictive WEIGHTS or
9803
+ * DATA, and the obligations (attribution, modification notices, source offers)
9804
+ * are per upstream. A persisted custom-model row written when this field was a
9805
+ * string still parses — the string is lifted into `{ weights }`.
9806
+ *
9807
+ * Every licence surface (the admin "Models and licenses" page,
9808
+ * `THIRD_PARTY_MODELS.md`, the Hugging Face model table) is GENERATED from
9809
+ * these records by `scripts/gen-model-licenses.ts` (D661).
9810
+ */
9811
+ var ModelLicenseSchema = preprocess((value) => typeof value === "string" ? { weights: value } : value, object({
9812
+ /** SPDX id of the WEIGHTS' terms, a `LicenseRef-*` for non-SPDX terms, or `UNKNOWN`. */
9813
+ weights: string().min(1),
9814
+ /** SPDX id of the upstream code that defines / trained the network. */
9815
+ code: string().min(1).optional(),
9816
+ /** Training data whose terms add obligations (attribution, non-commercial). */
9817
+ data: object({
9818
+ name: string().min(1),
9819
+ terms: string().min(1),
9820
+ url: string().url().optional()
9821
+ }).optional(),
9822
+ /** The project the weights come from. Required on built-in entries (guard). */
9823
+ upstream: object({
9824
+ name: string().min(1),
9825
+ url: string().url()
9826
+ }).optional(),
9827
+ /** Where the licence text governing the weights is published. */
9828
+ url: string().url().optional(),
9829
+ /** Attribution the licence REQUIRES, verbatim. */
9830
+ attribution: string().min(1).optional(),
9831
+ /** What CamStack changed. Required when `hosting` is `camstack-hf` (guard). */
9832
+ modifications: string().min(1).optional(),
9833
+ /** Who serves the file a node downloads. */
9834
+ hosting: _enum([
9835
+ "camstack-hf",
9836
+ "third-party",
9837
+ "built-in"
9838
+ ]).optional(),
9839
+ /** True when the weights or their data forbid commercial use. */
9840
+ nonCommercial: boolean().optional()
9841
+ }));
9800
9842
  var ModelCatalogEntrySchema = object({
9801
9843
  id: string(),
9802
9844
  name: string(),
@@ -9885,11 +9927,11 @@ var ModelCatalogEntrySchema = object({
9885
9927
  p95LatencyMs: record(string(), number$1()).optional()
9886
9928
  }).optional(),
9887
9929
  /**
9888
- * SPDX-ish license id of the model weights (e.g. `AGPL-3.0` for Ultralytics
9889
- * YOLO26, `GPL-3.0` for YOLOv9, `Apache-2.0` for D-FINE/RF-DETR). Matters for
9890
- * the retraining addon and any future commercial distribution.
9930
+ * The model's licence record — see {@link ModelLicenseSchema}. Optional in
9931
+ * the schema (a custom model's author may state none); REQUIRED and complete
9932
+ * on every built-in catalog entry (`scripts/check-catalog-licence.ts`).
9891
9933
  */
9892
- license: string().optional(),
9934
+ license: ModelLicenseSchema.optional(),
9893
9935
  /**
9894
9936
  * Variant-selector grouping. The UI groups models by `family` + `tier` and
9895
9937
  * offers `precision` / `optimization` as variant axes WITHIN a tier — so all
@@ -11198,12 +11240,32 @@ var AudioClassificationLabelSchema = object({
11198
11240
  originalClass: string().optional(),
11199
11241
  score: number$1()
11200
11242
  });
11243
+ /**
11244
+ * Did the classifier RUN on this window? (D660)
11245
+ *
11246
+ * `classified` with no labels means the model heard nothing above the
11247
+ * camera's floor. `not-classified` means nobody listened — and until D660 the
11248
+ * two were the same shape (`classification` absent), so a window the global
11249
+ * busy gate threw away read downstream exactly like a quiet one (D393).
11250
+ */
11251
+ var AudioClassifyOutcomeSchema = discriminatedUnion("state", [object({ state: literal("classified") }), object({
11252
+ state: literal("not-classified"),
11253
+ reason: _enum([
11254
+ "superseded",
11255
+ "error",
11256
+ "timeout",
11257
+ "disposed"
11258
+ ])
11259
+ })]);
11201
11260
  var AudioAnalysisResultSchema = object({
11202
11261
  level: AudioLevelSchema,
11262
+ /** Labels at or above the camera's floor. Absent = none — read `classifyOutcome` to know whether the model ran at all. */
11203
11263
  classification: object({
11204
11264
  labels: array(AudioClassificationLabelSchema).readonly(),
11205
11265
  inferenceMs: number$1()
11206
11266
  }).optional(),
11267
+ /** Whether the classifier ran on this window (D660). */
11268
+ classifyOutcome: AudioClassifyOutcomeSchema,
11207
11269
  timestamp: number$1()
11208
11270
  });
11209
11271
  var AudioAnalysisSettingsSchema = object({
@@ -14140,8 +14202,22 @@ var LinkedDeviceSchema = object({
14140
14202
  * The `linked-devices` extension slot's editable value (D648): the operator's
14141
14203
  * pick list, exactly what `_linkedDeviceIds` persists. Tree children are NOT
14142
14204
  * in it — they are always linked and are not a pick.
14143
- */
14144
- var LinkedDevicesSlotValueSchema = object({ deviceIds: array(number$1().int().positive()) });
14205
+ *
14206
+ * `trackedDeviceIds` (D655) is the tracked-event opt-in, exactly what
14207
+ * `_linkedDeviceTrackedIds` persists: which linked devices materialize a
14208
+ * synthetic tracked event on the camera. A read always carries it AS STORED
14209
+ * (an absent key reads as `[]`, which is what the resolver makes of it —
14210
+ * NONE). On a write it is optional: absent leaves the opt-in untouched, so a
14211
+ * card built before D655 cannot erase it by saving the pick list. A present
14212
+ * list REPLACES the opt-in; each id must be a pick, a device the camera links
14213
+ * by structure (the row's `impliedSources`: tree children, a picked
14214
+ * container's child) or already stored — so what was read can always be
14215
+ * written back unchanged, and a NEW opt-in outside the linked set is refused.
14216
+ */
14217
+ var LinkedDevicesSlotValueSchema = object({
14218
+ deviceIds: array(number$1().int().positive()),
14219
+ trackedDeviceIds: array(number$1().int().positive()).optional()
14220
+ });
14145
14221
  DeviceType.Camera;
14146
14222
  /** One camera's resolved linked set, tagged with the camera it belongs to.
14147
14223
  * The batch answer needs the tag; the single-device answer already has it
@@ -20580,6 +20656,13 @@ var AudioEventSchema = object({
20580
20656
  originalClass: string().optional(),
20581
20657
  score: number$1()
20582
20658
  }).optional(),
20659
+ /**
20660
+ * Whether the classifier RAN on the window behind this row (D660). Absent
20661
+ * on rows written before D660 — unknown, NOT classified: until then a
20662
+ * window the analyzer's busy gate threw away was stored exactly like one
20663
+ * that heard nothing above the floor.
20664
+ */
20665
+ classifyOutcome: AudioClassifyOutcomeSchema.optional(),
20583
20666
  /** Populated by B5 (recording playback URL for this event). */
20584
20667
  mediaUrl: string().optional()
20585
20668
  });
@@ -22171,7 +22254,14 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
22171
22254
  height: number$1()
22172
22255
  }), { kind: "mutation" }), method(object({
22173
22256
  stepId: string(),
22174
- frameId: number$1().int()
22257
+ frameId: number$1().int(),
22258
+ /**
22259
+ * The model to time — REQUIRED (D658). Without it the pool answered the
22260
+ * step's ACTIVE variant (the first loaded after boot), so a benchmark
22261
+ * of model B silently timed model A. Callers pass the `rootModelId`
22262
+ * their warmup `runPipeline` reported: the model that actually ran.
22263
+ */
22264
+ modelId: string().min(1)
22175
22265
  }), record(string(), unknown()), { kind: "mutation" }), method(object({ frameId: number$1().int() }), _void(), { kind: "mutation" }), method(object({ deviceKey: string().optional() }), EffectiveTuningSchema), method(_void(), array(object({
22176
22266
  engineKey: string(),
22177
22267
  engine: PipelineEngineChoiceSchema,
@@ -26133,7 +26223,17 @@ var ExtensionSlotRowSchema = discriminatedUnion("state", [object({
26133
26223
  projects: string().nullable(),
26134
26224
  activation: ExtensionSlotActivationSchema.nullable(),
26135
26225
  value: ExtensionSlotValueSchema,
26136
- sources: array(ExtensionSlotSourceSchema)
26226
+ sources: array(ExtensionSlotSourceSchema),
26227
+ /**
26228
+ * Devices the owner links to the host ON ITS OWN, by structure, and that
26229
+ * are therefore not in `value` (D655): a camera's device-tree children, and
26230
+ * the child a picked container stands for (D356 — a container is never a
26231
+ * pick, its children are). Read-only; the editor shows them and may offer
26232
+ * per-device options on them (the linked-devices tracked-event opt-in).
26233
+ * Absent when the owner links nothing beyond the picks, and from an owner
26234
+ * older than D655.
26235
+ */
26236
+ impliedSources: array(ExtensionSlotSourceSchema).optional()
26137
26237
  }), object({
26138
26238
  state: literal("unreachable"),
26139
26239
  addonId: string(),
@@ -37623,12 +37723,6 @@ Object.freeze({
37623
37723
  addonId: null,
37624
37724
  access: "create"
37625
37725
  },
37626
- "deviceManager.applyDeviceSettingsPatch": {
37627
- capName: "device-manager",
37628
- capScope: "system",
37629
- addonId: null,
37630
- access: "create"
37631
- },
37632
37726
  "deviceManager.applyInitialMeta": {
37633
37727
  capName: "device-manager",
37634
37728
  capScope: "system",
@@ -37731,12 +37825,6 @@ Object.freeze({
37731
37825
  addonId: null,
37732
37826
  access: "view"
37733
37827
  },
37734
- "deviceManager.getDeviceLiveContribution": {
37735
- capName: "device-manager",
37736
- capScope: "system",
37737
- addonId: null,
37738
- access: "view"
37739
- },
37740
37828
  "deviceManager.getDeviceLiveInfoAggregate": {
37741
37829
  capName: "device-manager",
37742
37830
  capScope: "system",
@@ -37749,12 +37837,6 @@ Object.freeze({
37749
37837
  addonId: null,
37750
37838
  access: "view"
37751
37839
  },
37752
- "deviceManager.getDeviceSettingsContribution": {
37753
- capName: "device-manager",
37754
- capScope: "system",
37755
- addonId: null,
37756
- access: "view"
37757
- },
37758
37840
  "deviceManager.getDeviceStatusAggregate": {
37759
37841
  capName: "device-manager",
37760
37842
  capScope: "system",
@@ -38259,24 +38341,6 @@ Object.freeze({
38259
38341
  addonId: null,
38260
38342
  access: "view"
38261
38343
  },
38262
- "doorbell.applyDeviceSettingsPatch": {
38263
- capName: "doorbell",
38264
- capScope: "device",
38265
- addonId: null,
38266
- access: "create"
38267
- },
38268
- "doorbell.getDeviceLiveContribution": {
38269
- capName: "doorbell",
38270
- capScope: "device",
38271
- addonId: null,
38272
- access: "view"
38273
- },
38274
- "doorbell.getDeviceSettingsContribution": {
38275
- capName: "doorbell",
38276
- capScope: "device",
38277
- addonId: null,
38278
- access: "view"
38279
- },
38280
38344
  "doorbell.getStatus": {
38281
38345
  capName: "doorbell",
38282
38346
  capScope: "device",
@@ -83843,6 +83907,53 @@ function createLlmProvider(deps) {
83843
83907
  };
83844
83908
  }
83845
83909
  //#endregion
83910
+ //#region src/runtime/llm-model-licenses.ts
83911
+ var QWEN_ATTRIBUTION = "Qwen models © Alibaba Cloud, Apache-2.0.";
83912
+ var QWEN_APACHE = {
83913
+ weights: "Apache-2.0",
83914
+ upstream: {
83915
+ name: "Qwen (Alibaba Cloud)",
83916
+ url: "https://huggingface.co/Qwen"
83917
+ },
83918
+ url: "https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct-GGUF",
83919
+ attribution: QWEN_ATTRIBUTION,
83920
+ modifications: "none (GGUF Q4_K_M published by Qwen; not re-hosted by CamStack)",
83921
+ hosting: "third-party"
83922
+ };
83923
+ var LLAMA_32_COMMUNITY = {
83924
+ weights: "LicenseRef-Llama-3.2-Community",
83925
+ upstream: {
83926
+ name: "Meta Llama 3.2 (GGUF by bartowski)",
83927
+ url: "https://huggingface.co/bartowski/Llama-3.2-3B-Instruct-GGUF"
83928
+ },
83929
+ url: "https://github.com/meta-llama/llama-models/blob/main/models/llama3_2/LICENSE",
83930
+ attribution: "Built with Llama. Llama 3.2 is licensed under the Llama 3.2 Community License, Copyright © Meta Platforms, Inc. All Rights Reserved.",
83931
+ modifications: "Q4_K_M GGUF quantisation by bartowski (not re-hosted by CamStack)",
83932
+ hosting: "third-party"
83933
+ };
83934
+ var QWEN_VL_APACHE = {
83935
+ weights: "Apache-2.0",
83936
+ upstream: {
83937
+ name: "Qwen3-VL (GGUF by unsloth)",
83938
+ url: "https://huggingface.co/unsloth"
83939
+ },
83940
+ url: "https://huggingface.co/Qwen/Qwen3-VL-8B-Instruct",
83941
+ attribution: QWEN_ATTRIBUTION,
83942
+ modifications: "Q4_K_M GGUF quantisation by unsloth (not re-hosted by CamStack)",
83943
+ hosting: "third-party"
83944
+ };
83945
+ var QWEN36_APACHE = {
83946
+ weights: "Apache-2.0",
83947
+ upstream: {
83948
+ name: "Qwen3.6-35B-A3B (GGUF by unsloth)",
83949
+ url: "https://huggingface.co/unsloth/Qwen3.6-35B-A3B-GGUF"
83950
+ },
83951
+ url: "https://huggingface.co/Qwen/Qwen3.6-35B-A3B/blob/main/LICENSE",
83952
+ attribution: QWEN_ATTRIBUTION,
83953
+ modifications: "UD-Q4_K_M GGUF quantisation by unsloth (not re-hosted by CamStack)",
83954
+ hosting: "third-party"
83955
+ };
83956
+ //#endregion
83846
83957
  //#region src/runtime/llm-model-catalog.ts
83847
83958
  /**
83848
83959
  * Curated managed-model catalog (operator decision #4). Each entry carries BOTH
@@ -83873,7 +83984,7 @@ var GIB = 1024 * 1024 * 1024;
83873
83984
  function mb(bytes) {
83874
83985
  return Math.round(bytes / (1024 * 1024));
83875
83986
  }
83876
- function textEntry(meta) {
83987
+ function textEntry(meta, license) {
83877
83988
  return {
83878
83989
  meta,
83879
83990
  entry: {
@@ -83888,7 +83999,8 @@ function textEntry(meta) {
83888
83999
  width: 0,
83889
84000
  height: 0
83890
84001
  },
83891
- labels: []
84002
+ labels: [],
84003
+ license
83892
84004
  }
83893
84005
  };
83894
84006
  }
@@ -83903,7 +84015,7 @@ var QWEN = textEntry({
83903
84015
  quantization: "Q4_K_M",
83904
84016
  minRamBytes: 2 * GIB,
83905
84017
  contextSizeDefault: 4096
83906
- });
84018
+ }, QWEN_APACHE);
83907
84019
  var LLAMA = textEntry({
83908
84020
  id: "llm-llama3.2-3b-instruct-q4",
83909
84021
  label: "Llama 3.2 3B Instruct",
@@ -83915,7 +84027,7 @@ var LLAMA = textEntry({
83915
84027
  quantization: "Q4_K_M",
83916
84028
  minRamBytes: Math.round(3.5 * GIB),
83917
84029
  contextSizeDefault: 4096
83918
- });
84030
+ }, LLAMA_32_COMMUNITY);
83919
84031
  var QWEN3VL2B_MODEL_BYTES = 1107410624;
83920
84032
  var QWEN3VL2B_MMPROJ_BYTES = 819395232;
83921
84033
  var QWEN3VL2B_BASE = "https://huggingface.co/unsloth/Qwen3-VL-2B-Instruct-GGUF/resolve/main";
@@ -83944,6 +84056,7 @@ var QWEN3VL_2B = {
83944
84056
  },
83945
84057
  entry: {
83946
84058
  id: "llm-qwen3-vl-2b-instruct-q4",
84059
+ license: QWEN_VL_APACHE,
83947
84060
  name: "Qwen3-VL 2B Instruct (vision, light)",
83948
84061
  description: "qwen3-vl · Q4_K_M · +mmproj",
83949
84062
  formats: { gguf: {
@@ -83998,6 +84111,7 @@ var QWEN3VL_4B = {
83998
84111
  },
83999
84112
  entry: {
84000
84113
  id: "llm-qwen3-vl-4b-instruct-q4",
84114
+ license: QWEN_VL_APACHE,
84001
84115
  name: "Qwen3-VL 4B Instruct (vision)",
84002
84116
  description: "qwen3-vl · Q4_K_M · +mmproj",
84003
84117
  formats: { gguf: {
@@ -84049,6 +84163,7 @@ var QWEN3VL_8B = {
84049
84163
  },
84050
84164
  entry: {
84051
84165
  id: "llm-qwen3-vl-8b-instruct-q4",
84166
+ license: QWEN_VL_APACHE,
84052
84167
  name: "Qwen3-VL 8B Instruct (vision)",
84053
84168
  description: "qwen3-vl · Q4_K_M · +mmproj",
84054
84169
  formats: { gguf: {
@@ -84094,6 +84209,7 @@ var LLM_MODEL_CATALOG = [
84094
84209
  },
84095
84210
  entry: {
84096
84211
  id: "llm-qwen3.6-35b-a3b-ud-q4",
84212
+ license: QWEN36_APACHE,
84097
84213
  name: "Qwen3.6 35B-A3B (vision)",
84098
84214
  description: "qwen3.6 · UD-Q4_K_M · +mmproj",
84099
84215
  formats: { gguf: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-ai",
3
- "version": "0.4.125",
3
+ "version": "0.4.126",
4
4
  "description": "AI addon for CamStack — the `llm` collection provider (cloud, LAN, and camstack-managed local llama.cpp profiles) plus the per-node `llm-runtime` managed executor.",
5
5
  "keywords": [
6
6
  "camstack",