@camstack/addon-model-studio 1.1.148 → 1.1.150

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.
Files changed (20) hide show
  1. package/dist/{MotionZonesSettings-CutK_Rge.mjs → MotionZonesSettings-DWornIU1.mjs} +2 -2
  2. package/dist/{PrivacyMaskSettings-BIyfXEbo.mjs → PrivacyMaskSettings-C8Cbjmjv.mjs} +4 -4
  3. package/dist/{SceneMonitorEditor-2Y8rhmM7.mjs → SceneMonitorEditor-CW0uHKtV.mjs} +3 -3
  4. package/dist/_stub.js +10 -10
  5. package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DepMCeHg.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CBP66bnV.mjs} +3 -3
  6. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-wFwZr9Eh.mjs +26 -0
  7. package/dist/addon-model-studio.css +1 -1
  8. package/dist/{hostInit-WBXJesb6.mjs → hostInit-BAxmLRKF.mjs} +2 -2
  9. package/dist/model-studio.addon.js +154 -3
  10. package/dist/model-studio.addon.mjs +154 -3
  11. package/dist/{player-overlays-CJLMB8Oi.mjs → player-overlays-lKz7g_ug.mjs} +1 -1
  12. package/dist/remoteEntry.js +1 -1
  13. package/dist/{responsive-B530NHNU.mjs → responsive-C_el8QKy.mjs} +1 -1
  14. package/dist/{scene-monitor-copy-dGEKyirP.mjs → scene-monitor-copy-nl2DVaph.mjs} +1 -1
  15. package/dist/{square-Pw2f7QBS.mjs → square-D1aA4m2u.mjs} +1 -1
  16. package/dist/{trash-2-C662Ujcb.mjs → trash-2-BQeBYO8f.mjs} +1 -1
  17. package/dist/{virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-A5OjQFZU.mjs → virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-BGFPAWqu.mjs} +1 -1
  18. package/package.json +1 -1
  19. package/python/convert_lib.py +34 -1
  20. package/dist/_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DWTM5JML.mjs +0 -26
@@ -5884,7 +5884,7 @@ var ZodIssueCode = {
5884
5884
  var ZodFirstPartyTypeKind;
5885
5885
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5886
5886
  //#endregion
5887
- //#region ../types/dist/sleep-GU_us3DG.mjs
5887
+ //#region ../types/dist/sleep-CiR4z7r9.mjs
5888
5888
  /**
5889
5889
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5890
5890
  * window to float samples (D455).
@@ -7026,6 +7026,17 @@ var CamProfileSchema = _enum([
7026
7026
  "mid",
7027
7027
  "low"
7028
7028
  ]);
7029
+ /**
7030
+ * Which rung a per-camera consumer listens on: an explicit profile, or `auto`.
7031
+ *
7032
+ * `auto` is a REAL value, not an absent one — it means "resolve it by the rule
7033
+ * that consumer owns". It lives beside `CamProfile` because a rung is the only
7034
+ * operator-facing way to name a stream: a cam-stream id is broker-internal and
7035
+ * moves when a slot is reassigned, so a stored id silently stops meaning what
7036
+ * the operator picked. Today's one user is the audio analyser, whose rule is
7037
+ * "the lowest AVAILABLE native rung" (D537).
7038
+ */
7039
+ var AudioStreamPickSchema = union([CamProfileSchema, literal("auto")]);
7029
7040
  var CamStreamKindSchema = _enum([
7030
7041
  "pull-rtsp",
7031
7042
  "pull-rtmp",
@@ -20482,6 +20493,7 @@ var MediaFileKindEnum = _enum([
20482
20493
  "keyFrameSmall",
20483
20494
  "thumbnailSmall",
20484
20495
  "confirmationCrop",
20496
+ "debugCrop",
20485
20497
  "sceneFrame"
20486
20498
  ]);
20487
20499
  /**
@@ -22146,6 +22158,18 @@ var RunnerCameraConfigSchema = object({
22146
22158
  motionStreamId: string(),
22147
22159
  detectionStreamId: string(),
22148
22160
  /**
22161
+ * Which rung this camera's audio analysis listens on — `auto` (the lowest
22162
+ * AVAILABLE native rung) or an explicit one.
22163
+ *
22164
+ * Not consumed by the runner: carried here so it travels with the camera's
22165
+ * config the way `audioMotionWindowMs` does, and so the orchestrator's
22166
+ * watchdog resolves the same stream the audio subscription did. OPTIONAL
22167
+ * with no default — absent means `auto`, which is what every camera written
22168
+ * before this field had, and an absent optional adds nothing to the
22169
+ * generated cap-input defaults (D537).
22170
+ */
22171
+ audioStreamPick: AudioStreamPickSchema.optional(),
22172
+ /**
22149
22173
  * Motion sources that can activate the pipeline. At least one must
22150
22174
  * be present. Multiple sources OR-ed: any one firing arms the
22151
22175
  * cooldown timer and transitions watching → active. The same
@@ -24637,6 +24661,104 @@ var WebrtcStreamChoiceSchema = object({
24637
24661
  /** Bitrate in kbps (null for adaptive). */
24638
24662
  bitrateKbps: number().nullable()
24639
24663
  });
24664
+ /**
24665
+ * The last move the adaptive ladder made on this session, and the numbers it
24666
+ * rested on. Mirrors `LadderDecision` in the stream-broker's
24667
+ * `adaptive-controller.ts` — the log line's evidence, made readable.
24668
+ *
24669
+ * Nullability is load-bearing: `lossRatio: null` means the loss tracker had
24670
+ * no window to report, which is NOT a link with zero loss.
24671
+ */
24672
+ var WebrtcLadderDecisionSchema = object({
24673
+ /** `loss` — RTCP / client-reported packet loss; `stall` — the picture
24674
+ * stopped moving; `healthy` — a promotion. */
24675
+ cause: _enum([
24676
+ "loss",
24677
+ "stall",
24678
+ "healthy"
24679
+ ]),
24680
+ /** The rung the ladder moved TO. Null for a move that changed no rung
24681
+ * (an MTU reduction, a forced transcode-down at the bottom). */
24682
+ tier: CamProfileSchema.nullable(),
24683
+ /** Whether that move forced the egress transcode-down rung. */
24684
+ forcedTranscodeDown: boolean(),
24685
+ /** Loss ratio over the tracker's window at the moment of the decision. */
24686
+ lossRatio: number().nullable(),
24687
+ /** The client's reported downlink at that moment, in kbps. */
24688
+ clientKbps: number().nullable(),
24689
+ /** How long the stall detector had been seeing nothing arrive. */
24690
+ stalledForMs: number().nullable(),
24691
+ /** Whether the broker WAS sending while that was measured — the half that
24692
+ * separates "the camera stopped" from "the link stopped". */
24693
+ serverSending: boolean().nullable(),
24694
+ /** Epoch ms. The overlay prints its age; a decision from 40 minutes ago
24695
+ * must not read like one from this second. */
24696
+ at: number()
24697
+ });
24698
+ /** Per-tier count of MEASURED downgrades this viewer session has suffered. */
24699
+ var WebrtcTierFailureSchema = object({
24700
+ tier: CamProfileSchema,
24701
+ failures: number().int().nonnegative()
24702
+ });
24703
+ /**
24704
+ * What the SERVER decided for one WebRTC session — the half the client cannot
24705
+ * measure. See `getSessionDebug`.
24706
+ */
24707
+ var WebrtcSessionDebugSchema = object({
24708
+ sessionId: string(),
24709
+ /** Whether the session still exists here. Everything below is null when
24710
+ * it does not — a dead session has no measurements, not zero ones. */
24711
+ alive: boolean(),
24712
+ /** Epoch ms this snapshot was taken, so the overlay can show its age. */
24713
+ observedAt: number(),
24714
+ /** The broker actually feeding this session (`<deviceId>/<camStreamId>`). */
24715
+ brokerId: string().nullable(),
24716
+ camStreamId: string().nullable(),
24717
+ /** `derived` = this hub BUILT the rung being served (a transcode/scale of
24718
+ * another stream); `native` = the camera's own encode. */
24719
+ sourceKind: _enum([
24720
+ "native",
24721
+ "derived",
24722
+ "unknown"
24723
+ ]),
24724
+ /** Whether the ladder is running at all (an `adaptive` target). */
24725
+ adaptive: boolean(),
24726
+ /** The rung `auto` ACTUALLY resolved to right now. Null when the broker
24727
+ * is bound to no profile slot (a manually-activated stream). */
24728
+ servedTier: CamProfileSchema.nullable(),
24729
+ /** Which node ingests the source. Null when unresolved. */
24730
+ ingestNodeId: string().nullable(),
24731
+ /** Whether that node is a remote one (the media crosses a node boundary
24732
+ * before it reaches this session). Null when unresolved. */
24733
+ ingestIsRemote: boolean().nullable(),
24734
+ /** Codec off the source, and the one negotiated with this client. */
24735
+ sourceCodec: string().nullable(),
24736
+ negotiatedCodec: string().nullable(),
24737
+ /** Whether the EGRESS leg re-encodes for this client or forwards the
24738
+ * source bytes untouched. */
24739
+ egressLeg: _enum([
24740
+ "copy",
24741
+ "transcode",
24742
+ "unknown"
24743
+ ]),
24744
+ /** What the broker itself reports about the rung it is serving. */
24745
+ brokerStatus: string().nullable(),
24746
+ brokerCodec: string().nullable(),
24747
+ brokerBitrateKbps: number().nullable(),
24748
+ brokerInputFps: number().nullable(),
24749
+ brokerUptimeMs: number().nullable(),
24750
+ /** RTP packets this session has sent — the server's own "am I sending?". */
24751
+ rtpPacketsSent: number().nullable(),
24752
+ /** D42: the track may be carrying the recorded feeder, not live. The ladder
24753
+ * is suspended there, so a frozen picture in `recorded` mode means
24754
+ * something entirely different. */
24755
+ trackMode: _enum(["live", "recorded"]).nullable(),
24756
+ lastDecision: WebrtcLadderDecisionSchema.nullable(),
24757
+ tierFailures: array(WebrtcTierFailureSchema),
24758
+ /** Successful promotions in this viewer session (drives the progressive
24759
+ * healthy timer). Null when no ladder is running. */
24760
+ upgradeCount: number().nullable()
24761
+ });
24640
24762
  DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), array(WebrtcStreamChoiceSchema)), method(object({
24641
24763
  deviceId: number().int().nonnegative(),
24642
24764
  target: WebrtcStreamTargetSchema,
@@ -24801,7 +24923,10 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
24801
24923
  * the same answer as "it ended": either way nothing is holding it up.
24802
24924
  */
24803
24925
  alive: boolean()
24804
- }));
24926
+ })), method(object({
24927
+ deviceId: number().int().nonnegative(),
24928
+ sessionId: string()
24929
+ }), WebrtcSessionDebugSchema, { kind: "query" });
24805
24930
  object({
24806
24931
  /** All accessory children of the parent. */
24807
24932
  childDeviceIds: array(number()).readonly(),
@@ -27897,7 +28022,16 @@ var GridProfileOfferSchema = object({
27897
28022
  * grid came out as, and because it is the number an operator would otherwise
27898
28023
  * expect to type.
27899
28024
  */
27900
- canvas: string()
28025
+ canvas: string(),
28026
+ /**
28027
+ * Whether this profile is PUBLISHED, of the ones the grid could serve.
28028
+ *
28029
+ * A grid's `high` is composed of its sources' `high`, so on a 4K fleet it is
28030
+ * a 4K canvas built from 4K decodes — something to opt into, not something a
28031
+ * viewer's adaptive should be handed by climbing to the top rung it can see.
28032
+ * Default is `mid` + `low`.
28033
+ */
28034
+ published: boolean()
27901
28035
  });
27902
28036
  var GridLayoutViewSchema = object({
27903
28037
  /** The persisted grid row this camera was declared from. */
@@ -27920,6 +28054,12 @@ var GridLayoutPatchSchema = object({
27920
28054
  deviceId: number().int().nonnegative(),
27921
28055
  name: string().min(1).max(160).optional(),
27922
28056
  fps: number().int().min(1).max(60).optional(),
28057
+ /** Which profiles to publish. See `GridProfileOffer.published`. */
28058
+ publishedProfiles: array(_enum([
28059
+ "high",
28060
+ "mid",
28061
+ "low"
28062
+ ])).max(3).optional(),
27923
28063
  /**
27924
28064
  * The whole cell list at once. A per-cell patch would need an ordering the
27925
28065
  * editor does not have, and a half-applied layout is a picture nobody asked
@@ -38474,6 +38614,12 @@ Object.freeze({
38474
38614
  addonId: null,
38475
38615
  access: "view"
38476
38616
  },
38617
+ "webrtcSession.getSessionDebug": {
38618
+ capName: "webrtc-session",
38619
+ capScope: "device",
38620
+ addonId: null,
38621
+ access: "view"
38622
+ },
38477
38623
  "webrtcSession.getSessionState": {
38478
38624
  capName: "webrtc-session",
38479
38625
  capScope: "device",
@@ -40457,6 +40603,11 @@ Object.freeze({
40457
40603
  form: "single",
40458
40604
  optional: false
40459
40605
  }],
40606
+ "webrtcSession.getSessionDebug": [{
40607
+ name: "deviceId",
40608
+ form: "single",
40609
+ optional: false
40610
+ }],
40460
40611
  "webrtcSession.getSessionState": [{
40461
40612
  name: "deviceId",
40462
40613
  form: "single",
@@ -5863,7 +5863,7 @@ var ZodIssueCode = {
5863
5863
  var ZodFirstPartyTypeKind;
5864
5864
  ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
5865
5865
  //#endregion
5866
- //#region ../types/dist/sleep-GU_us3DG.mjs
5866
+ //#region ../types/dist/sleep-CiR4z7r9.mjs
5867
5867
  /**
5868
5868
  * The audio chunk plane's byte format, and the ONE expansion from a coded
5869
5869
  * window to float samples (D455).
@@ -7005,6 +7005,17 @@ var CamProfileSchema = _enum([
7005
7005
  "mid",
7006
7006
  "low"
7007
7007
  ]);
7008
+ /**
7009
+ * Which rung a per-camera consumer listens on: an explicit profile, or `auto`.
7010
+ *
7011
+ * `auto` is a REAL value, not an absent one — it means "resolve it by the rule
7012
+ * that consumer owns". It lives beside `CamProfile` because a rung is the only
7013
+ * operator-facing way to name a stream: a cam-stream id is broker-internal and
7014
+ * moves when a slot is reassigned, so a stored id silently stops meaning what
7015
+ * the operator picked. Today's one user is the audio analyser, whose rule is
7016
+ * "the lowest AVAILABLE native rung" (D537).
7017
+ */
7018
+ var AudioStreamPickSchema = union([CamProfileSchema, literal("auto")]);
7008
7019
  var CamStreamKindSchema = _enum([
7009
7020
  "pull-rtsp",
7010
7021
  "pull-rtmp",
@@ -20461,6 +20472,7 @@ var MediaFileKindEnum = _enum([
20461
20472
  "keyFrameSmall",
20462
20473
  "thumbnailSmall",
20463
20474
  "confirmationCrop",
20475
+ "debugCrop",
20464
20476
  "sceneFrame"
20465
20477
  ]);
20466
20478
  /**
@@ -22125,6 +22137,18 @@ var RunnerCameraConfigSchema = object({
22125
22137
  motionStreamId: string(),
22126
22138
  detectionStreamId: string(),
22127
22139
  /**
22140
+ * Which rung this camera's audio analysis listens on — `auto` (the lowest
22141
+ * AVAILABLE native rung) or an explicit one.
22142
+ *
22143
+ * Not consumed by the runner: carried here so it travels with the camera's
22144
+ * config the way `audioMotionWindowMs` does, and so the orchestrator's
22145
+ * watchdog resolves the same stream the audio subscription did. OPTIONAL
22146
+ * with no default — absent means `auto`, which is what every camera written
22147
+ * before this field had, and an absent optional adds nothing to the
22148
+ * generated cap-input defaults (D537).
22149
+ */
22150
+ audioStreamPick: AudioStreamPickSchema.optional(),
22151
+ /**
22128
22152
  * Motion sources that can activate the pipeline. At least one must
22129
22153
  * be present. Multiple sources OR-ed: any one firing arms the
22130
22154
  * cooldown timer and transitions watching → active. The same
@@ -24616,6 +24640,104 @@ var WebrtcStreamChoiceSchema = object({
24616
24640
  /** Bitrate in kbps (null for adaptive). */
24617
24641
  bitrateKbps: number().nullable()
24618
24642
  });
24643
+ /**
24644
+ * The last move the adaptive ladder made on this session, and the numbers it
24645
+ * rested on. Mirrors `LadderDecision` in the stream-broker's
24646
+ * `adaptive-controller.ts` — the log line's evidence, made readable.
24647
+ *
24648
+ * Nullability is load-bearing: `lossRatio: null` means the loss tracker had
24649
+ * no window to report, which is NOT a link with zero loss.
24650
+ */
24651
+ var WebrtcLadderDecisionSchema = object({
24652
+ /** `loss` — RTCP / client-reported packet loss; `stall` — the picture
24653
+ * stopped moving; `healthy` — a promotion. */
24654
+ cause: _enum([
24655
+ "loss",
24656
+ "stall",
24657
+ "healthy"
24658
+ ]),
24659
+ /** The rung the ladder moved TO. Null for a move that changed no rung
24660
+ * (an MTU reduction, a forced transcode-down at the bottom). */
24661
+ tier: CamProfileSchema.nullable(),
24662
+ /** Whether that move forced the egress transcode-down rung. */
24663
+ forcedTranscodeDown: boolean(),
24664
+ /** Loss ratio over the tracker's window at the moment of the decision. */
24665
+ lossRatio: number().nullable(),
24666
+ /** The client's reported downlink at that moment, in kbps. */
24667
+ clientKbps: number().nullable(),
24668
+ /** How long the stall detector had been seeing nothing arrive. */
24669
+ stalledForMs: number().nullable(),
24670
+ /** Whether the broker WAS sending while that was measured — the half that
24671
+ * separates "the camera stopped" from "the link stopped". */
24672
+ serverSending: boolean().nullable(),
24673
+ /** Epoch ms. The overlay prints its age; a decision from 40 minutes ago
24674
+ * must not read like one from this second. */
24675
+ at: number()
24676
+ });
24677
+ /** Per-tier count of MEASURED downgrades this viewer session has suffered. */
24678
+ var WebrtcTierFailureSchema = object({
24679
+ tier: CamProfileSchema,
24680
+ failures: number().int().nonnegative()
24681
+ });
24682
+ /**
24683
+ * What the SERVER decided for one WebRTC session — the half the client cannot
24684
+ * measure. See `getSessionDebug`.
24685
+ */
24686
+ var WebrtcSessionDebugSchema = object({
24687
+ sessionId: string(),
24688
+ /** Whether the session still exists here. Everything below is null when
24689
+ * it does not — a dead session has no measurements, not zero ones. */
24690
+ alive: boolean(),
24691
+ /** Epoch ms this snapshot was taken, so the overlay can show its age. */
24692
+ observedAt: number(),
24693
+ /** The broker actually feeding this session (`<deviceId>/<camStreamId>`). */
24694
+ brokerId: string().nullable(),
24695
+ camStreamId: string().nullable(),
24696
+ /** `derived` = this hub BUILT the rung being served (a transcode/scale of
24697
+ * another stream); `native` = the camera's own encode. */
24698
+ sourceKind: _enum([
24699
+ "native",
24700
+ "derived",
24701
+ "unknown"
24702
+ ]),
24703
+ /** Whether the ladder is running at all (an `adaptive` target). */
24704
+ adaptive: boolean(),
24705
+ /** The rung `auto` ACTUALLY resolved to right now. Null when the broker
24706
+ * is bound to no profile slot (a manually-activated stream). */
24707
+ servedTier: CamProfileSchema.nullable(),
24708
+ /** Which node ingests the source. Null when unresolved. */
24709
+ ingestNodeId: string().nullable(),
24710
+ /** Whether that node is a remote one (the media crosses a node boundary
24711
+ * before it reaches this session). Null when unresolved. */
24712
+ ingestIsRemote: boolean().nullable(),
24713
+ /** Codec off the source, and the one negotiated with this client. */
24714
+ sourceCodec: string().nullable(),
24715
+ negotiatedCodec: string().nullable(),
24716
+ /** Whether the EGRESS leg re-encodes for this client or forwards the
24717
+ * source bytes untouched. */
24718
+ egressLeg: _enum([
24719
+ "copy",
24720
+ "transcode",
24721
+ "unknown"
24722
+ ]),
24723
+ /** What the broker itself reports about the rung it is serving. */
24724
+ brokerStatus: string().nullable(),
24725
+ brokerCodec: string().nullable(),
24726
+ brokerBitrateKbps: number().nullable(),
24727
+ brokerInputFps: number().nullable(),
24728
+ brokerUptimeMs: number().nullable(),
24729
+ /** RTP packets this session has sent — the server's own "am I sending?". */
24730
+ rtpPacketsSent: number().nullable(),
24731
+ /** D42: the track may be carrying the recorded feeder, not live. The ladder
24732
+ * is suspended there, so a frozen picture in `recorded` mode means
24733
+ * something entirely different. */
24734
+ trackMode: _enum(["live", "recorded"]).nullable(),
24735
+ lastDecision: WebrtcLadderDecisionSchema.nullable(),
24736
+ tierFailures: array(WebrtcTierFailureSchema),
24737
+ /** Successful promotions in this viewer session (drives the progressive
24738
+ * healthy timer). Null when no ladder is running. */
24739
+ upgradeCount: number().nullable()
24740
+ });
24619
24741
  DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), array(WebrtcStreamChoiceSchema)), method(object({
24620
24742
  deviceId: number().int().nonnegative(),
24621
24743
  target: WebrtcStreamTargetSchema,
@@ -24780,7 +24902,10 @@ DeviceType.Camera, method(object({ deviceId: number().int().nonnegative() }), ar
24780
24902
  * the same answer as "it ended": either way nothing is holding it up.
24781
24903
  */
24782
24904
  alive: boolean()
24783
- }));
24905
+ })), method(object({
24906
+ deviceId: number().int().nonnegative(),
24907
+ sessionId: string()
24908
+ }), WebrtcSessionDebugSchema, { kind: "query" });
24784
24909
  object({
24785
24910
  /** All accessory children of the parent. */
24786
24911
  childDeviceIds: array(number()).readonly(),
@@ -27876,7 +28001,16 @@ var GridProfileOfferSchema = object({
27876
28001
  * grid came out as, and because it is the number an operator would otherwise
27877
28002
  * expect to type.
27878
28003
  */
27879
- canvas: string()
28004
+ canvas: string(),
28005
+ /**
28006
+ * Whether this profile is PUBLISHED, of the ones the grid could serve.
28007
+ *
28008
+ * A grid's `high` is composed of its sources' `high`, so on a 4K fleet it is
28009
+ * a 4K canvas built from 4K decodes — something to opt into, not something a
28010
+ * viewer's adaptive should be handed by climbing to the top rung it can see.
28011
+ * Default is `mid` + `low`.
28012
+ */
28013
+ published: boolean()
27880
28014
  });
27881
28015
  var GridLayoutViewSchema = object({
27882
28016
  /** The persisted grid row this camera was declared from. */
@@ -27899,6 +28033,12 @@ var GridLayoutPatchSchema = object({
27899
28033
  deviceId: number().int().nonnegative(),
27900
28034
  name: string().min(1).max(160).optional(),
27901
28035
  fps: number().int().min(1).max(60).optional(),
28036
+ /** Which profiles to publish. See `GridProfileOffer.published`. */
28037
+ publishedProfiles: array(_enum([
28038
+ "high",
28039
+ "mid",
28040
+ "low"
28041
+ ])).max(3).optional(),
27902
28042
  /**
27903
28043
  * The whole cell list at once. A per-cell patch would need an ordering the
27904
28044
  * editor does not have, and a half-applied layout is a picture nobody asked
@@ -38453,6 +38593,12 @@ Object.freeze({
38453
38593
  addonId: null,
38454
38594
  access: "view"
38455
38595
  },
38596
+ "webrtcSession.getSessionDebug": {
38597
+ capName: "webrtc-session",
38598
+ capScope: "device",
38599
+ addonId: null,
38600
+ access: "view"
38601
+ },
38456
38602
  "webrtcSession.getSessionState": {
38457
38603
  capName: "webrtc-session",
38458
38604
  capScope: "device",
@@ -40436,6 +40582,11 @@ Object.freeze({
40436
40582
  form: "single",
40437
40583
  optional: false
40438
40584
  }],
40585
+ "webrtcSession.getSessionDebug": [{
40586
+ name: "deviceId",
40587
+ form: "single",
40588
+ optional: false
40589
+ }],
40439
40590
  "webrtcSession.getSessionState": [{
40440
40591
  name: "deviceId",
40441
40592
  form: "single",
@@ -1,5 +1,5 @@
1
1
  import { h as e, l as t, u as n, y as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
2
- import { o as i, s as a } from "./responsive-B530NHNU.mjs";
2
+ import { o as i, s as a } from "./responsive-C_el8QKy.mjs";
3
3
  import { n as o, r as s, t as c } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
4
4
  var l = a("chevron-down", [["path", {
5
5
  d: "m6 9 6 6 6-6",
@@ -1,2 +1,2 @@
1
- import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-A5OjQFZU.mjs";
1
+ import { n as e, t } from "./virtual_mf-REMOTE_ENTRY_ID___mfe_internal__addon_model_studio_page__remoteEntry_js-BGFPAWqu.mjs";
2
2
  export { t as get, e as init };
@@ -1,6 +1,6 @@
1
1
  import { c as e, g as t, h as n, l as r, n as i, p as a, r as o, t as s, u as c, y as l } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
2
2
  import "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react_mf_1_jsx_mf_2_runtime__loadShare__.js-ds_Ehzaa.mjs";
3
- import { n as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-DWTM5JML.mjs";
3
+ import { n as u } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-wFwZr9Eh.mjs";
4
4
  //#region ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.js
5
5
  l();
6
6
  var d = (...e) => e.filter((e, t, n) => !!e && e.trim() !== "" && n.indexOf(e) === t).join(" ").trim(), f = (e) => e.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase(), p = (e) => e.replace(/^([A-Z])|[\s-_]+(\w)/g, (e, t, n) => n ? n.toUpperCase() : t.toLowerCase()), m = (e) => {
@@ -1,5 +1,5 @@
1
1
  import { c as e, h as t, p as n, y as r } from "./_virtual_mf___mfe_internal__addon_model_studio_page__loadShare__react__loadShare__.js-DJDHChgO.mjs";
2
- import { s as i } from "./responsive-B530NHNU.mjs";
2
+ import { s as i } from "./responsive-C_el8QKy.mjs";
3
3
  var a = i("camera", [["path", {
4
4
  d: "M13.997 4a2 2 0 0 1 1.76 1.05l.486.9A2 2 0 0 0 18.003 7H20a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V9a2 2 0 0 1 2-2h1.997a2 2 0 0 0 1.759-1.048l.489-.904A2 2 0 0 1 10.004 4z",
5
5
  key: "18u6gg"
@@ -1,4 +1,4 @@
1
- import { s as e } from "./responsive-B530NHNU.mjs";
1
+ import { s as e } from "./responsive-C_el8QKy.mjs";
2
2
  var t = e("eye-off", [
3
3
  ["path", {
4
4
  d: "M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",
@@ -1,4 +1,4 @@
1
- import { s as e } from "./responsive-B530NHNU.mjs";
1
+ import { s as e } from "./responsive-C_el8QKy.mjs";
2
2
  var t = e("trash-2", [
3
3
  ["path", {
4
4
  d: "M10 11v6",
@@ -2753,7 +2753,7 @@ async function rr(e) {
2753
2753
  }
2754
2754
  }
2755
2755
  async function ir() {
2756
- return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-DepMCeHg.mjs")).catch((e) => {
2756
+ return tr ||= rr(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_model_studio_page-CBP66bnV.mjs")).catch((e) => {
2757
2757
  throw tr = void 0, e;
2758
2758
  }), tr;
2759
2759
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-model-studio",
3
- "version": "1.1.148",
3
+ "version": "1.1.150",
4
4
  "description": "Custom detection model registry, conversion & distribution for CamStack",
5
5
  "keywords": [
6
6
  "camstack",
@@ -5,8 +5,26 @@ scripts/build-camstack-models.py. Conversion ALWAYS starts from ONNX via
5
5
  ov.convert_model (never the Ultralytics OV exporter, which emits unnamed
6
6
  tensors that break the runtime's named-output postprocess)."""
7
7
  from __future__ import annotations
8
+ import os
8
9
  from pathlib import Path
9
10
 
11
+ # OpenVINO sizes the pool that COMPILES a model to the machine's core count and
12
+ # TBB never gives those workers back. A container cgroup counts THREADS, and
13
+ # this one has been measured refusing forks against `pids.max=2048` — so a
14
+ # conversion running beside the live pools must not spend `nproc` of the budget
15
+ # just to validate an IR. Same knob, same env var and same default (4) as
16
+ # OV_COMPILATION_NUM_THREADS in
17
+ # packages/addon-pipeline/python/inference_pool.py, which carries the
18
+ # measurement; this process is short-lived, so the saving here is a spike, not
19
+ # the 214-thread accumulation that motivated the bound. 0 disables it.
20
+ _OV_COMPILATION_NUM_THREADS: int = 4
21
+ try:
22
+ _OV_COMPILATION_NUM_THREADS = int(
23
+ os.environ.get("CAMSTACK_OV_COMPILATION_THREADS", "4")
24
+ )
25
+ except ValueError:
26
+ _OV_COMPILATION_NUM_THREADS = 4
27
+
10
28
 
11
29
  def export_openvino(onnx_path: str, out_xml: str, *, fp16: bool) -> None:
12
30
  import openvino as ov
@@ -21,7 +39,22 @@ def validate_openvino_ir(xml_path: str) -> None:
21
39
  import openvino as ov
22
40
  core = ov.Core()
23
41
  model = core.read_model(xml_path)
24
- compiled = core.compile_model(model, "CPU")
42
+ # Bound the compilation pool (see _OV_COMPILATION_NUM_THREADS). A plugin
43
+ # REJECTS a property it does not know, and this compile is the VALIDATION —
44
+ # it must never fail for a reason that has nothing to do with the IR, so a
45
+ # refused property falls back to the unbounded compile rather than
46
+ # reporting a bad model.
47
+ if _OV_COMPILATION_NUM_THREADS > 0:
48
+ try:
49
+ compiled = core.compile_model(
50
+ model,
51
+ "CPU",
52
+ {"COMPILATION_NUM_THREADS": _OV_COMPILATION_NUM_THREADS},
53
+ )
54
+ except Exception:
55
+ compiled = core.compile_model(model, "CPU")
56
+ else:
57
+ compiled = core.compile_model(model, "CPU")
25
58
  for port in list(compiled.inputs) + list(compiled.outputs):
26
59
  try:
27
60
  name = port.get_any_name()