@trillboards/edge-sdk 0.2.92 → 0.2.94

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.
@@ -347,7 +347,183 @@ RFDETR_MEDIUM = ModelVocabulary(
347
347
  #: nothing (see `ClassIndex`, built over models whose file is present), and
348
348
  #: publishing is a separate task. What changed is that the service can now
349
349
  #: EXPRESS a second entry, which before this it structurally could not.
350
- BUILTIN_VOCABULARIES: "tuple[ModelVocabulary, ...]" = (RFDETR_MEDIUM,)
350
+ #: Forklift Detector — published 2026-08-25 by
351
+ #: scripts/sensing/publish-sensing-model.js. The class list is the artifact's own
352
+ #: (graph metadata key 'names'); the footprint is MEASURED, 119.0938 MiB after a
353
+ #: probe inference via rusage-maxrss, not an estimate from the file size.
354
+ #: Coordinate space MEASURED, not assumed: max|box channel| = 640.0000 over 110 real frames; / imgsz 640 = 1.0000. pixels at >= 0.2, normalized at <= 0.02, refused in between.
355
+ GH_FORKLIFT_COMBINE_CLASS_NAMES: "MappingProxyType[int, str]" = MappingProxyType({
356
+ 0: "forklift",
357
+ 1: "forklift partial",
358
+ })
359
+
360
+ GH_FORKLIFT_COMBINE = ModelVocabulary(
361
+ model_name="gh_forklift_combine",
362
+ slot_names=GH_FORKLIFT_COMBINE_CLASS_NAMES,
363
+ logit_slots=2,
364
+ approx_ram_bytes=124878901,
365
+ onnx_variant=VariantContract(
366
+ output_layout="anchor_4_plus_nc",
367
+ box_units="pixels",
368
+ box_scale_to_pixels=1.0,
369
+ ),
370
+ )
371
+
372
+ #: PPE Detector (hard hat) — published 2026-08-25 by
373
+ #: scripts/sensing/publish-sensing-model.js. The class list is the artifact's own
374
+ #: (graph metadata key 'names'); the footprint is MEASURED, 420.5156 MiB after a
375
+ #: probe inference via rusage-maxrss, not an estimate from the file size.
376
+ #: Coordinate space MEASURED, not assumed: max|box channel| = 640.0000 over 110 real frames; / imgsz 640 = 1.0000. pixels at >= 0.2, normalized at <= 0.02, refused in between.
377
+ PPE_VYRA_14CLS_V8M_CLASS_NAMES: "MappingProxyType[int, str]" = MappingProxyType({
378
+ 0: "fall detected",
379
+ 1: "gloves",
380
+ 2: "goggles",
381
+ 3: "hardhat",
382
+ 4: "ladder",
383
+ 5: "mask",
384
+ 6: "no gloves",
385
+ 7: "no goggles",
386
+ 8: "no hardhat",
387
+ 9: "no mask",
388
+ 10: "no safety vest",
389
+ 11: "person",
390
+ 12: "safety cone",
391
+ 13: "safety vest",
392
+ })
393
+
394
+ PPE_VYRA_14CLS_V8M = ModelVocabulary(
395
+ model_name="ppe_vyra_14cls_v8m",
396
+ slot_names=PPE_VYRA_14CLS_V8M_CLASS_NAMES,
397
+ logit_slots=14,
398
+ approx_ram_bytes=440942566,
399
+ onnx_variant=VariantContract(
400
+ output_layout="anchor_4_plus_nc",
401
+ box_units="pixels",
402
+ box_scale_to_pixels=1.0,
403
+ ),
404
+ )
405
+
406
+ #: Heavy Machinery Detector — published 2026-08-25 by
407
+ #: scripts/sensing/publish-sensing-model.js. The class list is the artifact's own
408
+ #: (graph metadata key 'names'); the footprint is MEASURED, 118.6875 MiB after a
409
+ #: probe inference via rusage-maxrss, not an estimate from the file size.
410
+ #: Coordinate space MEASURED, not assumed: max|box channel| = 1832.0278 over 120 real frames; / imgsz 640 = 2.8625. pixels at >= 0.2, normalized at <= 0.02, refused in between.
411
+ PPE_CONSTRUCTION_17CLS_V8N_CLASS_NAMES: "MappingProxyType[int, str]" = MappingProxyType({
412
+ 0: "barricade",
413
+ 1: "dumpster",
414
+ 2: "excavators",
415
+ 3: "gloves",
416
+ 4: "hardhat",
417
+ 5: "mask",
418
+ 6: "no hardhat",
419
+ 7: "no mask",
420
+ 8: "no safety vest",
421
+ 9: "person",
422
+ 10: "safety net",
423
+ 11: "safety shoes",
424
+ 12: "safety vest",
425
+ 13: "dump truck",
426
+ 14: "mini van",
427
+ 15: "truck",
428
+ 16: "wheel loader",
429
+ })
430
+
431
+ PPE_CONSTRUCTION_17CLS_V8N = ModelVocabulary(
432
+ model_name="ppe_construction_17cls_v8n",
433
+ slot_names=PPE_CONSTRUCTION_17CLS_V8N_CLASS_NAMES,
434
+ logit_slots=17,
435
+ approx_ram_bytes=124452864,
436
+ onnx_variant=VariantContract(
437
+ output_layout="anchor_4_plus_nc",
438
+ box_units="pixels",
439
+ box_scale_to_pixels=1.0,
440
+ ),
441
+ )
442
+
443
+ #: Fire-Safety Detector — published 2026-08-25 by
444
+ #: scripts/sensing/publish-sensing-model.js. The class list is the artifact's own
445
+ #: (graph metadata key 'names'); the footprint is MEASURED, 239.25 MiB after a
446
+ #: probe inference via rusage-maxrss, not an estimate from the file size.
447
+ #: Coordinate space MEASURED, not assumed: max|box channel| = 1971.5000 over 100 real frames; / imgsz 640 = 3.0805. pixels at >= 0.2, normalized at <= 0.02, refused in between.
448
+ PPE_KILLUMINATI_19CLS_V8S_CLASS_NAMES: "MappingProxyType[int, str]" = MappingProxyType({
449
+ 0: "boots",
450
+ 1: "ear protection",
451
+ 2: "glass",
452
+ 3: "glove",
453
+ 4: "hard hat",
454
+ 5: "mask",
455
+ 6: "no boots",
456
+ 7: "no ear protection",
457
+ 8: "no glass",
458
+ 9: "no glove",
459
+ 10: "no helmet",
460
+ 11: "no mask",
461
+ 12: "no vest",
462
+ 13: "worker",
463
+ 14: "vest",
464
+ 15: "circular saw",
465
+ 16: "fire extinguisher",
466
+ 17: "fire prevention net",
467
+ 18: "welding equipment",
468
+ })
469
+
470
+ PPE_KILLUMINATI_19CLS_V8S = ModelVocabulary(
471
+ model_name="ppe_killuminati_19cls_v8s",
472
+ slot_names=PPE_KILLUMINATI_19CLS_V8S_CLASS_NAMES,
473
+ logit_slots=19,
474
+ approx_ram_bytes=250871808,
475
+ onnx_variant=VariantContract(
476
+ output_layout="anchor_4_plus_nc",
477
+ box_units="pixels",
478
+ box_scale_to_pixels=1.0,
479
+ ),
480
+ )
481
+
482
+ #: FIVE SPECIALISTS WERE SCORED; FOUR ARE HERE. `gh_fall_tonlong` IS ABSENT ON
483
+ #: PURPOSE, AND THIS NOTE IS WHY IT MUST STAY ABSENT.
484
+ #:
485
+ #: It has a committed score card and a committed 94-frame eval set, and its
486
+ #: numbers are good — the `fall` gate fits at 0.7924 with precision 1.0 and
487
+ #: recall 1.0 on the held-out half. It is not withheld for being weak.
488
+ #:
489
+ #: It is withheld because its own exporter named two logit slots the same word:
490
+ #: the graph's `names` metadata is
491
+ #:
492
+ #: {0: 'Violence', 1: 'fall', 2: 'fire', 3: 'sit', 4: 'sleep',
493
+ #: 5: 'standing', 6: 'violence'}
494
+ #:
495
+ #: and `normalize_class_name` lowercases, so slots 0 and 6 both fold to
496
+ #: `violence`. SEVEN logit slots, SIX names. `ModelVocabulary.__post_init__`
497
+ #: refuses that pair — "two slots share one class name, so a filter would be
498
+ #: ambiguous" — because `_to_wire` puts the declared name on the wire and
499
+ #: `postprocess` filters on the canonical one, so the service could not attribute
500
+ #: a `violence` detection to a slot. The refusal is at CONSTRUCTION, so the
501
+ #: artifact would not load on a device: a registry row for it would be a row for
502
+ #: a model that can never answer, which is the `yolov8_nano` shape this whole
503
+ #: publish path exists to stop.
504
+ #:
505
+ #: AND IT CANNOT BE PAPERED OVER FROM OUR SIDE. `_resolve_slot_names` in
506
+ #: `scripts/sensing/onnx_artifact_probe.py` is deliberately NOT a precedence
507
+ #: order — every source that exists must AGREE — so a `--classes-file` cannot
508
+ #: override the graph, only restate it, collision included. Renaming one of the
509
+ #: two would also be a guess about which logit the exporter wired, and a wrong
510
+ #: guess is invisible: the boxes stay real and the counts stay plausible while
511
+ #: every `violence` answer names the wrong slot.
512
+ #:
513
+ #: WHAT UNBLOCKS IT is a re-export with one spelling per class, which changes the
514
+ #: bytes and therefore the sha256 — so it is a NEW artifact that must be scored
515
+ #: again before it can ship. `person_fall` is already a legal `corpus_name` in
516
+ #: both CHECK constraints and holds zero fixtures, which is inert while no
517
+ #: registry row names it (and `publish-sensing-model.js` refuses to deploy
518
+ #: against an empty corpus), so the family is ready for that artifact and is
519
+ #: waiting on nothing else.
520
+ #:
521
+ #: The collision is not folklore: `tests/test_onnx_artifact_probe.py`
522
+ #: (TestFourPlusNcCountsLogitSlots) pins `slot_map[0] == slot_map[6]` and uses
523
+ #: this artifact as the fixture that exercises `_verify_class_axis_width`, where
524
+ #: `4 + 7 = 11` matches its real `[1, 11, 8400]` head and `4 + 6 = 10` would
525
+ #: reject it.
526
+ BUILTIN_VOCABULARIES: "tuple[ModelVocabulary, ...]" = (RFDETR_MEDIUM, GH_FORKLIFT_COMBINE, PPE_VYRA_14CLS_V8M, PPE_CONSTRUCTION_17CLS_V8N, PPE_KILLUMINATI_19CLS_V8S,)
351
527
 
352
528
 
353
529
  class ClassIndex:
@@ -441,6 +617,10 @@ class ClassIndex:
441
617
 
442
618
 
443
619
  __all__ = [
620
+ "PPE_KILLUMINATI_19CLS_V8S",
621
+ "PPE_CONSTRUCTION_17CLS_V8N",
622
+ "PPE_VYRA_14CLS_V8M",
623
+ "GH_FORKLIFT_COMBINE",
444
624
  "ANCHOR_4_PLUS_NC",
445
625
  "BOX_UNITS",
446
626
  "BOX_UNITS_NORMALIZED",
package/dist/EdgeAgent.js CHANGED
@@ -44,7 +44,7 @@ const edge_ads_1 = require("@trillboards/edge-ads");
44
44
  const CommandRouter_1 = require("./CommandRouter");
45
45
  const config_1 = require("./config");
46
46
  const dataDir_1 = require("./dataDir");
47
- const SDK_VERSION = '0.2.92';
47
+ const SDK_VERSION = '0.2.94';
48
48
  class EdgeAgent extends events_1.EventEmitter {
49
49
  constructor(config, deps) {
50
50
  super();
@@ -31,7 +31,7 @@ export interface DiagnosticReport {
31
31
  skipped: number;
32
32
  };
33
33
  }
34
- declare const SDK_VERSION = "0.2.92";
34
+ declare const SDK_VERSION = "0.2.94";
35
35
  declare function checkNodeVersion(): CheckResult;
36
36
  declare function checkPlatform(): CheckResult;
37
37
  declare function checkMemory(): CheckResult;
package/dist/diagnose.js CHANGED
@@ -63,7 +63,7 @@ const localNetworkAccess_1 = require("./localNetworkAccess");
63
63
  // ---------------------------------------------------------------------------
64
64
  // SDK version — mirrors package.json; kept in sync by CI
65
65
  // ---------------------------------------------------------------------------
66
- const SDK_VERSION = '0.2.92';
66
+ const SDK_VERSION = '0.2.94';
67
67
  exports._SDK_VERSION = SDK_VERSION;
68
68
  // ---------------------------------------------------------------------------
69
69
  // ANSI helpers (no external deps)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@trillboards/edge-sdk",
3
- "version": "0.2.92",
3
+ "version": "0.2.94",
4
4
  "description": "Composable cross-platform Edge AI SDK for audience sensing on DOOH/CTV devices",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -30,7 +30,14 @@
30
30
  "@trillboards/edge-platform-rtsp": "^0.2.0",
31
31
  "@trillboards/edge-platform-windows": "^0.2.0"
32
32
  },
33
- "files": ["dist", "configs", "deploy", "LICENSE", "THIRD-PARTY-NOTICES.md", "README.md"],
33
+ "files": [
34
+ "dist",
35
+ "configs",
36
+ "deploy",
37
+ "LICENSE",
38
+ "THIRD-PARTY-NOTICES.md",
39
+ "README.md"
40
+ ],
34
41
  "engines": {
35
42
  "node": ">=18.0.0"
36
43
  },