@camstack/types 1.2.327 → 1.2.329

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 (72) hide show
  1. package/dist/addon/base-addon.d.ts +58 -0
  2. package/dist/addon/secret-aware-context.d.ts +27 -0
  3. package/dist/addon/secret-paths.d.ts +48 -0
  4. package/dist/addon/secret-settings-view.d.ts +80 -0
  5. package/dist/addon.d.ts +1 -0
  6. package/dist/addon.js +52 -4
  7. package/dist/addon.mjs +27 -5
  8. package/dist/capabilities/addons.cap.d.ts +4 -4
  9. package/dist/capabilities/alarm-panel.cap.d.ts +8 -8
  10. package/dist/capabilities/alerts.cap.d.ts +5 -5
  11. package/dist/capabilities/control.cap.d.ts +11 -11
  12. package/dist/capabilities/day-night.cap.d.ts +16 -16
  13. package/dist/capabilities/device-manager.cap.d.ts +2 -0
  14. package/dist/capabilities/enum-sensor.cap.d.ts +4 -4
  15. package/dist/capabilities/index.d.ts +6 -2
  16. package/dist/capabilities/integrations.cap.d.ts +6 -3
  17. package/dist/capabilities/keychain-admin.cap.d.ts +312 -0
  18. package/dist/capabilities/keychain.cap.d.ts +180 -0
  19. package/dist/capabilities/lawn-mower-control.cap.d.ts +4 -4
  20. package/dist/capabilities/log-channels.cap.d.ts +1 -1
  21. package/dist/capabilities/log-destination.cap.d.ts +5 -5
  22. package/dist/capabilities/notification-rules.cap.d.ts +118 -118
  23. package/dist/capabilities/osd-manager.cap.d.ts +11 -11
  24. package/dist/capabilities/osd.cap.d.ts +5 -5
  25. package/dist/capabilities/pipeline-analytics.cap.d.ts +1291 -118
  26. package/dist/capabilities/pipeline-orchestrator.cap.d.ts +384 -0
  27. package/dist/capabilities/pipeline-runner.cap.d.ts +145 -2
  28. package/dist/capabilities/storage.cap.d.ts +1 -1
  29. package/dist/capabilities/system.cap.d.ts +16 -16
  30. package/dist/capabilities/webrtc-session.cap.d.ts +3 -3
  31. package/dist/client.js +37 -1
  32. package/dist/client.mjs +37 -1
  33. package/dist/device/device-context.d.ts +11 -1
  34. package/dist/device/index.d.ts +1 -1
  35. package/dist/enums/event-category.d.ts +7 -0
  36. package/dist/enums.js +1 -1
  37. package/dist/enums.mjs +1 -1
  38. package/dist/{event-category-CtBAl88K.js → event-category-CHduMGvg.js} +7 -0
  39. package/dist/{event-category-B_0XEcLF.mjs → event-category-DaIZi00R.mjs} +7 -0
  40. package/dist/generated/addon-api.d.ts +289 -0
  41. package/dist/generated/cap-input-defaults.d.ts +1 -1
  42. package/dist/generated/capability-router-map.d.ts +8 -2
  43. package/dist/generated/method-access-map.d.ts +1 -1
  44. package/dist/generated/method-device-selectors.d.ts +1 -1
  45. package/dist/generated/system-proxy.d.ts +4 -2
  46. package/dist/health/wiring-health.d.ts +8 -8
  47. package/dist/index.d.ts +6 -2
  48. package/dist/index.js +1881 -101
  49. package/dist/index.mjs +1766 -98
  50. package/dist/interfaces/addon.d.ts +25 -0
  51. package/dist/interfaces/config-ui-secrets.d.ts +12 -0
  52. package/dist/interfaces/config-ui.d.ts +29 -1
  53. package/dist/interfaces/event-bus.d.ts +11 -0
  54. package/dist/interfaces/pipeline-runner-capability.d.ts +18 -0
  55. package/dist/keychain/index.d.ts +5 -0
  56. package/dist/keychain/known-secrets.d.ts +31 -0
  57. package/dist/keychain/resolve-secret-views.d.ts +2 -0
  58. package/dist/keychain/secret-marker.d.ts +52 -0
  59. package/dist/keychain/secret-ref.d.ts +62 -0
  60. package/dist/keychain/secrets-access.d.ts +77 -0
  61. package/dist/logging/log-channel.d.ts +2 -2
  62. package/dist/pipeline/auto-tune/plan-schemas.d.ts +123 -0
  63. package/dist/pipeline/auto-tune/recommend.d.ts +26 -1
  64. package/dist/pipeline/load-balancing/schemas.d.ts +8 -7
  65. package/dist/pipeline/node-benchmark/benchmark-mode.d.ts +57 -0
  66. package/dist/pipeline/node-benchmark/index.d.ts +9 -0
  67. package/dist/pipeline/node-benchmark/results.d.ts +52 -0
  68. package/dist/pipeline/node-benchmark/schemas.d.ts +848 -0
  69. package/dist/pipeline/node-benchmark/step-tree.d.ts +23 -0
  70. package/dist/{sleep-az1qiFzK.js → sleep-ClNXPpWR.js} +1580 -121
  71. package/dist/{sleep-B0JG7-_F.mjs → sleep-DujUvOcb.mjs} +1340 -121
  72. package/package.json +1 -1
@@ -78,12 +78,39 @@ export declare const RecommendationReasonSchema: z.ZodDiscriminatedUnion<[z.ZodO
78
78
  pt: "pt";
79
79
  gguf: "gguf";
80
80
  }>;
81
+ }, z.core.$strip>, z.ZodObject<{
82
+ kind: z.ZodLiteral<"kept-custom-pin">;
83
+ modelId: z.ZodString;
84
+ deviceKey: z.ZodString;
85
+ }, z.core.$strip>], "kind">;
86
+ /** Why a device is left exactly as it is, whatever the plan would pick (D786). */
87
+ export declare const KeptReasonSchema: z.ZodEnum<{
88
+ "custom-pin": "custom-pin";
89
+ }>;
90
+ /**
91
+ * Where a choice's latency came from (D791): this node's own benchmark
92
+ * result, or the hardware-class table. Measured on the node beats the table.
93
+ */
94
+ export declare const LatencySourceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
95
+ kind: z.ZodLiteral<"table">;
96
+ }, z.core.$strip>, z.ZodObject<{
97
+ kind: z.ZodLiteral<"node-benchmark">;
98
+ resultId: z.ZodString;
99
+ measuredAtMs: z.ZodNumber;
81
100
  }, z.core.$strip>], "kind">;
101
+ export type LatencySource = z.infer<typeof LatencySourceSchema>;
82
102
  export declare const DeviceModelChoiceSchema: z.ZodObject<{
83
103
  modelId: z.ZodString;
84
104
  p50Ms: z.ZodNumber;
85
105
  fps: z.ZodNumber;
86
106
  measured: z.ZodBoolean;
107
+ source: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
108
+ kind: z.ZodLiteral<"table">;
109
+ }, z.core.$strip>, z.ZodObject<{
110
+ kind: z.ZodLiteral<"node-benchmark">;
111
+ resultId: z.ZodString;
112
+ measuredAtMs: z.ZodNumber;
113
+ }, z.core.$strip>], "kind">>;
87
114
  capacitySessions: z.ZodNumber;
88
115
  personRecall: z.ZodNumber;
89
116
  }, z.core.$strip>;
@@ -104,9 +131,19 @@ export declare const DeviceRecommendationSchema: z.ZodObject<{
104
131
  p50Ms: z.ZodNumber;
105
132
  fps: z.ZodNumber;
106
133
  measured: z.ZodBoolean;
134
+ source: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
135
+ kind: z.ZodLiteral<"table">;
136
+ }, z.core.$strip>, z.ZodObject<{
137
+ kind: z.ZodLiteral<"node-benchmark">;
138
+ resultId: z.ZodString;
139
+ measuredAtMs: z.ZodNumber;
140
+ }, z.core.$strip>], "kind">>;
107
141
  capacitySessions: z.ZodNumber;
108
142
  personRecall: z.ZodNumber;
109
143
  }, z.core.$strip>>;
144
+ kept: z.ZodOptional<z.ZodEnum<{
145
+ "custom-pin": "custom-pin";
146
+ }>>;
110
147
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
111
148
  kind: z.ZodLiteral<"capacity">;
112
149
  sessions: z.ZodNumber;
@@ -158,6 +195,10 @@ export declare const DeviceRecommendationSchema: z.ZodObject<{
158
195
  pt: "pt";
159
196
  gguf: "gguf";
160
197
  }>;
198
+ }, z.core.$strip>, z.ZodObject<{
199
+ kind: z.ZodLiteral<"kept-custom-pin">;
200
+ modelId: z.ZodString;
201
+ deviceKey: z.ZodString;
161
202
  }, z.core.$strip>], "kind">>>;
162
203
  }, z.core.$strip>;
163
204
  export declare const NodeRecommendationSchema: z.ZodObject<{
@@ -190,9 +231,19 @@ export declare const NodeRecommendationSchema: z.ZodObject<{
190
231
  p50Ms: z.ZodNumber;
191
232
  fps: z.ZodNumber;
192
233
  measured: z.ZodBoolean;
234
+ source: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
235
+ kind: z.ZodLiteral<"table">;
236
+ }, z.core.$strip>, z.ZodObject<{
237
+ kind: z.ZodLiteral<"node-benchmark">;
238
+ resultId: z.ZodString;
239
+ measuredAtMs: z.ZodNumber;
240
+ }, z.core.$strip>], "kind">>;
193
241
  capacitySessions: z.ZodNumber;
194
242
  personRecall: z.ZodNumber;
195
243
  }, z.core.$strip>>;
244
+ kept: z.ZodOptional<z.ZodEnum<{
245
+ "custom-pin": "custom-pin";
246
+ }>>;
196
247
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
197
248
  kind: z.ZodLiteral<"capacity">;
198
249
  sessions: z.ZodNumber;
@@ -244,6 +295,10 @@ export declare const NodeRecommendationSchema: z.ZodObject<{
244
295
  pt: "pt";
245
296
  gguf: "gguf";
246
297
  }>;
298
+ }, z.core.$strip>, z.ZodObject<{
299
+ kind: z.ZodLiteral<"kept-custom-pin">;
300
+ modelId: z.ZodString;
301
+ deviceKey: z.ZodString;
247
302
  }, z.core.$strip>], "kind">>>;
248
303
  }, z.core.$strip>>>;
249
304
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -297,6 +352,10 @@ export declare const NodeRecommendationSchema: z.ZodObject<{
297
352
  pt: "pt";
298
353
  gguf: "gguf";
299
354
  }>;
355
+ }, z.core.$strip>, z.ZodObject<{
356
+ kind: z.ZodLiteral<"kept-custom-pin">;
357
+ modelId: z.ZodString;
358
+ deviceKey: z.ZodString;
300
359
  }, z.core.$strip>], "kind">>>;
301
360
  }, z.core.$strip>;
302
361
  export declare const ModelPinChangeSchema: z.ZodObject<{
@@ -344,6 +403,15 @@ export declare const AutoTuneWarningSchema: z.ZodDiscriminatedUnion<[z.ZodObject
344
403
  kind: z.ZodLiteral<"coral-enabled">;
345
404
  nodeId: z.ZodString;
346
405
  deviceKey: z.ZodString;
406
+ }, z.core.$strip>, z.ZodObject<{
407
+ kind: z.ZodLiteral<"custom-pin-kept">;
408
+ nodeId: z.ZodString;
409
+ deviceKey: z.ZodNullable<z.ZodString>;
410
+ deviceId: z.ZodNullable<z.ZodNumber>;
411
+ modelId: z.ZodString;
412
+ }, z.core.$strip>, z.ZodObject<{
413
+ kind: z.ZodLiteral<"custom-registry-unreadable">;
414
+ error: z.ZodString;
347
415
  }, z.core.$strip>], "kind">;
348
416
  export declare const AutoTuneOptionsSchema: z.ZodObject<{
349
417
  headroom: z.ZodDefault<z.ZodNumber>;
@@ -386,9 +454,19 @@ export declare const AutoTunePlanSchema: z.ZodObject<{
386
454
  p50Ms: z.ZodNumber;
387
455
  fps: z.ZodNumber;
388
456
  measured: z.ZodBoolean;
457
+ source: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
458
+ kind: z.ZodLiteral<"table">;
459
+ }, z.core.$strip>, z.ZodObject<{
460
+ kind: z.ZodLiteral<"node-benchmark">;
461
+ resultId: z.ZodString;
462
+ measuredAtMs: z.ZodNumber;
463
+ }, z.core.$strip>], "kind">>;
389
464
  capacitySessions: z.ZodNumber;
390
465
  personRecall: z.ZodNumber;
391
466
  }, z.core.$strip>>;
467
+ kept: z.ZodOptional<z.ZodEnum<{
468
+ "custom-pin": "custom-pin";
469
+ }>>;
392
470
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
393
471
  kind: z.ZodLiteral<"capacity">;
394
472
  sessions: z.ZodNumber;
@@ -440,6 +518,10 @@ export declare const AutoTunePlanSchema: z.ZodObject<{
440
518
  pt: "pt";
441
519
  gguf: "gguf";
442
520
  }>;
521
+ }, z.core.$strip>, z.ZodObject<{
522
+ kind: z.ZodLiteral<"kept-custom-pin">;
523
+ modelId: z.ZodString;
524
+ deviceKey: z.ZodString;
443
525
  }, z.core.$strip>], "kind">>>;
444
526
  }, z.core.$strip>>>;
445
527
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -493,6 +575,10 @@ export declare const AutoTunePlanSchema: z.ZodObject<{
493
575
  pt: "pt";
494
576
  gguf: "gguf";
495
577
  }>;
578
+ }, z.core.$strip>, z.ZodObject<{
579
+ kind: z.ZodLiteral<"kept-custom-pin">;
580
+ modelId: z.ZodString;
581
+ deviceKey: z.ZodString;
496
582
  }, z.core.$strip>], "kind">>>;
497
583
  }, z.core.$strip>>>;
498
584
  nodeChanges: z.ZodReadonly<z.ZodArray<z.ZodObject<{
@@ -535,6 +621,15 @@ export declare const AutoTunePlanSchema: z.ZodObject<{
535
621
  kind: z.ZodLiteral<"coral-enabled">;
536
622
  nodeId: z.ZodString;
537
623
  deviceKey: z.ZodString;
624
+ }, z.core.$strip>, z.ZodObject<{
625
+ kind: z.ZodLiteral<"custom-pin-kept">;
626
+ nodeId: z.ZodString;
627
+ deviceKey: z.ZodNullable<z.ZodString>;
628
+ deviceId: z.ZodNullable<z.ZodNumber>;
629
+ modelId: z.ZodString;
630
+ }, z.core.$strip>, z.ZodObject<{
631
+ kind: z.ZodLiteral<"custom-registry-unreadable">;
632
+ error: z.ZodString;
538
633
  }, z.core.$strip>], "kind">>>;
539
634
  }, z.core.$strip>;
540
635
  export declare const AutoTuneApplyInputSchema: z.ZodObject<{
@@ -619,9 +714,19 @@ export declare const AutoTuneApplyResultSchema: z.ZodDiscriminatedUnion<[z.ZodOb
619
714
  p50Ms: z.ZodNumber;
620
715
  fps: z.ZodNumber;
621
716
  measured: z.ZodBoolean;
717
+ source: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
718
+ kind: z.ZodLiteral<"table">;
719
+ }, z.core.$strip>, z.ZodObject<{
720
+ kind: z.ZodLiteral<"node-benchmark">;
721
+ resultId: z.ZodString;
722
+ measuredAtMs: z.ZodNumber;
723
+ }, z.core.$strip>], "kind">>;
622
724
  capacitySessions: z.ZodNumber;
623
725
  personRecall: z.ZodNumber;
624
726
  }, z.core.$strip>>;
727
+ kept: z.ZodOptional<z.ZodEnum<{
728
+ "custom-pin": "custom-pin";
729
+ }>>;
625
730
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
626
731
  kind: z.ZodLiteral<"capacity">;
627
732
  sessions: z.ZodNumber;
@@ -673,6 +778,10 @@ export declare const AutoTuneApplyResultSchema: z.ZodDiscriminatedUnion<[z.ZodOb
673
778
  pt: "pt";
674
779
  gguf: "gguf";
675
780
  }>;
781
+ }, z.core.$strip>, z.ZodObject<{
782
+ kind: z.ZodLiteral<"kept-custom-pin">;
783
+ modelId: z.ZodString;
784
+ deviceKey: z.ZodString;
676
785
  }, z.core.$strip>], "kind">>>;
677
786
  }, z.core.$strip>>>;
678
787
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
@@ -726,6 +835,10 @@ export declare const AutoTuneApplyResultSchema: z.ZodDiscriminatedUnion<[z.ZodOb
726
835
  pt: "pt";
727
836
  gguf: "gguf";
728
837
  }>;
838
+ }, z.core.$strip>, z.ZodObject<{
839
+ kind: z.ZodLiteral<"kept-custom-pin">;
840
+ modelId: z.ZodString;
841
+ deviceKey: z.ZodString;
729
842
  }, z.core.$strip>], "kind">>>;
730
843
  }, z.core.$strip>>>;
731
844
  nodeChanges: z.ZodReadonly<z.ZodArray<z.ZodObject<{
@@ -768,6 +881,15 @@ export declare const AutoTuneApplyResultSchema: z.ZodDiscriminatedUnion<[z.ZodOb
768
881
  kind: z.ZodLiteral<"coral-enabled">;
769
882
  nodeId: z.ZodString;
770
883
  deviceKey: z.ZodString;
884
+ }, z.core.$strip>, z.ZodObject<{
885
+ kind: z.ZodLiteral<"custom-pin-kept">;
886
+ nodeId: z.ZodString;
887
+ deviceKey: z.ZodNullable<z.ZodString>;
888
+ deviceId: z.ZodNullable<z.ZodNumber>;
889
+ modelId: z.ZodString;
890
+ }, z.core.$strip>, z.ZodObject<{
891
+ kind: z.ZodLiteral<"custom-registry-unreadable">;
892
+ error: z.ZodString;
771
893
  }, z.core.$strip>], "kind">>>;
772
894
  }, z.core.$strip>;
773
895
  }, z.core.$strip>, z.ZodObject<{
@@ -791,3 +913,4 @@ export type RecommendationReason = z.infer<typeof RecommendationReasonSchema>;
791
913
  export type DeviceModelChoice = z.infer<typeof DeviceModelChoiceSchema>;
792
914
  export type DeviceRecommendation = z.infer<typeof DeviceRecommendationSchema>;
793
915
  export type NodeRecommendation = z.infer<typeof NodeRecommendationSchema>;
916
+ export type KeptReason = z.infer<typeof KeptReasonSchema>;
@@ -6,7 +6,12 @@
6
6
  *
7
7
  * Per node:
8
8
  * 1. Classify the hardware (`classifyInferenceHardware`). An unknown class,
9
- * an offline node or a node with nothing to recommend is left untouched.
9
+ * an offline node or a node with nothing to recommend is left untouched —
10
+ * unless the node has its own measurements (below).
11
+ * 1b. MEASURED ON THE NODE BEATS THE TABLE (D791): a fresh node benchmark
12
+ * result for (device, model) replaces the table's cell, and the choice
13
+ * names it as its source. A node of unknown hardware with measurements is
14
+ * recommended from them alone.
10
15
  * 2. The node's ACCELERATORS (NPU, iGPU, Neural Engine) that are enabled and
11
16
  * available share ONE model — so a camera's floors never flip with the
12
17
  * device the balancer rotated it onto. A candidate must have a build for
@@ -21,6 +26,10 @@
21
26
  * the candidate with the most capacity is used and the plan says so.
22
27
  * 5. An enabled CPU device (the fallback pool) gets its own pick the same
23
28
  * way; a Coral is never touched (no YOLOv9 build), only reported.
29
+ * 6. A device whose root detector is pinned to a CUSTOM-registry model (a
30
+ * fine-tune, a canary) is KEPT (D786): no model is chosen for it, so Apply
31
+ * writes nothing there. One kept accelerator keeps the whole accelerator
32
+ * group, because the group shares one model.
24
33
  */
25
34
  import type { HardwareInfo } from '../../interfaces/platform.js';
26
35
  import type { ModelFormat } from '../../types/models.js';
@@ -36,12 +45,26 @@ export declare const DEFAULT_HEADROOM = 0.4;
36
45
  export declare const DEFAULT_CAMERA_FPS = 10;
37
46
  /** Parallel sessions one device sustains at `fps` with `headroom` kept free. */
38
47
  export declare function capacitySessionsOf(fps: number, headroom: number, cameraFps: number): number;
48
+ /** A latency measured on the node itself (a fresh node benchmark result, D791). */
49
+ export interface MeasuredLatencyCell {
50
+ readonly p50Ms: number;
51
+ readonly fps: number;
52
+ readonly resultId: string;
53
+ readonly measuredAtMs: number;
54
+ }
55
+ /** deviceKey → modelId → measured cell. */
56
+ export type MeasuredLatency = Readonly<Record<string, Readonly<Record<string, MeasuredLatencyCell>>>>;
39
57
  /** One device of a node, as the recommender reads it. */
40
58
  export interface AutoTuneDeviceInput {
41
59
  readonly key: string;
42
60
  readonly format: ModelFormat;
43
61
  readonly enabled: boolean;
44
62
  readonly available: boolean;
63
+ /**
64
+ * The custom-registry model the device's root detector is pinned to, when
65
+ * it is one (the caller decides what is custom). The device is then kept.
66
+ */
67
+ readonly customPinModelId?: string;
45
68
  }
46
69
  /** One node, as the recommender reads it. */
47
70
  export interface AutoTuneNodeInput {
@@ -61,4 +84,6 @@ export declare function recommendNode(input: {
61
84
  /** The rate a session is counted at (default {@link DEFAULT_CAMERA_FPS}). */
62
85
  readonly cameraFps?: number;
63
86
  readonly perf?: DetectorPerfTable;
87
+ /** This node's fresh node-benchmark measurements (D791); they beat the table. */
88
+ readonly measured?: MeasuredLatency;
64
89
  }): NodeRecommendation;
@@ -191,13 +191,14 @@ export declare const SuggestSharesResultSchema: z.ZodObject<{
191
191
  }, z.core.$strip>;
192
192
  export type SuggestSharesResult = z.infer<typeof SuggestSharesResultSchema>;
193
193
  /**
194
- * Where the node and device shares come from (D750, D755).
195
- * - `hardware` (default) — computed by the system from each node's static
196
- * capacity (its accelerators at their Auto tune models, from the measured
197
- * latency table), recomputed whenever a node or device joins, leaves, is
198
- * switched on or off, or changes model. No load input.
199
- * - `benchmark` — the same, from each node's measured capacity (node
200
- * benchmark results); a node without results falls back to `hardware`.
194
+ * Where the node and device shares come from (D750, D755, D791).
195
+ * - `benchmark` (default since D791) — each node's capacity as its own node
196
+ * benchmark measured it; a node without fresh results is sized from
197
+ * `hardware` and says so. Measured on the node beats the table.
198
+ * - `hardware` — computed from each node's static capacity only (its
199
+ * accelerators at their Auto tune models, from the latency table).
200
+ * Both are recomputed whenever a node or device joins, leaves, is switched
201
+ * on or off, changes model, or a benchmark result is written. No load input.
201
202
  * - `manual` — the operator's stored sliders.
202
203
  * Either way a node or device that cannot take sessions gives its share to
203
204
  * the others in proportion; the stored values are never rewritten for that.
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Benchmark mode (D791) — the pure rules of "one node under test". Pure.
3
+ *
4
+ * While the cluster is in benchmark mode for node N:
5
+ * - N is not a detection candidate for any camera that another node can
6
+ * serve ({@link eligibleUnderBenchmark});
7
+ * - a node pin naming N is ignored for such a camera
8
+ * ({@link pinUnderBenchmark}) — the stored pin is never rewritten, so it
9
+ * is "restored" the moment the mode ends;
10
+ * - a camera whose ONLY frame source is N stays on N (never blind) and the
11
+ * run is flagged contaminated.
12
+ */
13
+ import { type NodeBenchmarkMovingCamera, type NodeBenchmarkPlan, type NodeBenchmarkRefusal, type NodeBenchmarkStayingCamera } from './schemas.js';
14
+ /** The detection candidates of one camera while `benchNodeId` is under test. */
15
+ export declare function eligibleUnderBenchmark(eligible: readonly string[], benchNodeId: string | null): readonly string[];
16
+ /** A camera's node pin while `benchNodeId` is under test (null = no pin). */
17
+ export declare function pinUnderBenchmark(pin: string | null, benchNodeId: string | null, eligible: readonly string[]): string | null;
18
+ /** One camera as the preflight sees it. */
19
+ export interface BenchmarkCameraFacts {
20
+ readonly deviceId: number;
21
+ /** The node its detection is placed on now; null = not placed. */
22
+ readonly placedNodeId: string | null;
23
+ /** Its stored node pin; null = none. */
24
+ readonly nodePin: string | null;
25
+ /** Nodes that can obtain its frames (before the benchmark). */
26
+ readonly frameSourceNodes: readonly string[];
27
+ }
28
+ /** Which cameras leave the node for the run, and which cannot. */
29
+ export declare function classifyCamerasForBenchmark(nodeId: string, cameras: readonly BenchmarkCameraFacts[]): {
30
+ readonly moving: readonly NodeBenchmarkMovingCamera[];
31
+ readonly staying: readonly NodeBenchmarkStayingCamera[];
32
+ };
33
+ /** Ramp steps the runner tries per cell, at most. */
34
+ export declare const DEVICE_RAMP: readonly number[];
35
+ export declare const PIPELINE_RAMP: readonly number[];
36
+ /**
37
+ * An upper bound on how long the run takes: every ramp step of every cell,
38
+ * plus the drain, the clip and the restore — capped at the budget, which is
39
+ * the hard deadline anyway. A ramp usually stops well before its last step.
40
+ */
41
+ export declare function estimateNodeBenchmarkDurationMs(plan: NodeBenchmarkPlan, timing?: {
42
+ readonly settleSec?: number;
43
+ readonly measureSec?: number;
44
+ }): number;
45
+ /** Why a run cannot start, in the order the operator should read them. */
46
+ export declare function nodeBenchmarkRefusals(input: {
47
+ readonly plan: NodeBenchmarkPlan;
48
+ /** The node a run is active for, if any. */
49
+ readonly activeRunNodeId: string | null;
50
+ readonly online: boolean;
51
+ /** Inference devices the node reports. */
52
+ readonly knownDeviceKeys: readonly string[];
53
+ /** Parallel sessions the cluster runs now. */
54
+ readonly sessionsNow: number;
55
+ /** Sessions the OTHER nodes can carry; null = unknown. */
56
+ readonly otherNodesCapacitySessions: number | null;
57
+ }): readonly NodeBenchmarkRefusal[];
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Node benchmark (D791): one node at a time, owned by the pipeline
3
+ * orchestrator, measured by the node's own runner; its results feed Auto
4
+ * tune and the automatic shares. See `schemas.ts` and `benchmark-mode.ts`.
5
+ */
6
+ export * from './schemas.js';
7
+ export * from './benchmark-mode.js';
8
+ export * from './results.js';
9
+ export * from './step-tree.js';
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Which node benchmark result still beats the table (D791). Pure.
3
+ *
4
+ * A row is FRESH when it is the newest for its cell (node × device × phase
5
+ * × model [× steps]), younger than the stale bound (30 days), and was
6
+ * measured on the pool the node runs today (same runtime, same tuning). A
7
+ * fresh row is what Auto tune and the automatic shares read; anything else
8
+ * falls back to the latency table and says why.
9
+ *
10
+ * A pool the node does not answer for today does not make a row stale: an
11
+ * unreadable fact is not a changed one.
12
+ */
13
+ import type { NodeMeasuredCapacity } from '../load-balancing/capacity-shares.js';
14
+ import { type NodeBenchmarkResult, type NodeBenchmarkResultView } from './schemas.js';
15
+ /** The pool a device runs today, as `getEffectiveTuning` answers it. */
16
+ export interface CurrentPool {
17
+ readonly runtime: string;
18
+ readonly numWorkers: number;
19
+ readonly concurrency: number;
20
+ readonly batchMode: string;
21
+ }
22
+ export interface StandingContext {
23
+ readonly nowMs: number;
24
+ /** Default {@link NODE_BENCHMARK_DEFAULTS.staleAfterDays}. */
25
+ readonly staleAfterMs?: number;
26
+ /** nodeId → deviceKey → the pool now; a missing entry is "unknown", never "changed". */
27
+ readonly currentPools: Readonly<Record<string, Readonly<Record<string, CurrentPool>>>>;
28
+ }
29
+ export interface Standing {
30
+ readonly standing: NodeBenchmarkResultView['standing'];
31
+ readonly staleWhy: NodeBenchmarkResultView['staleWhy'];
32
+ }
33
+ /** The cell a row measures — two rows with the same key measure the same thing. */
34
+ export declare function resultCellKey(row: NodeBenchmarkResult): string;
35
+ /** The standing of every row, by id. */
36
+ export declare function resultStandings(rows: readonly NodeBenchmarkResult[], ctx: StandingContext): ReadonlyMap<string, Standing>;
37
+ /** Rows that beat the table today. */
38
+ export declare function freshResults(rows: readonly NodeBenchmarkResult[], ctx: StandingContext): readonly NodeBenchmarkResult[];
39
+ /** One measured detector on one device — what Auto tune overlays on the table. */
40
+ export interface MeasuredDetectorCell {
41
+ readonly p50Ms: number;
42
+ readonly fps: number;
43
+ readonly resultId: string;
44
+ readonly measuredAtMs: number;
45
+ }
46
+ /** deviceKey → modelId → the fresh `device` measurement on `nodeId`. */
47
+ export declare function measuredDetectorCells(rows: readonly NodeBenchmarkResult[], nodeId: string, ctx: StandingContext): Readonly<Record<string, Readonly<Record<string, MeasuredDetectorCell>>>>;
48
+ /**
49
+ * Per node, each device at its newest fresh `pipeline` measurement — the
50
+ * `NodeCapacitySource` answer the automatic shares read.
51
+ */
52
+ export declare function measuredCapacityFromResults(rows: readonly NodeBenchmarkResult[], nodeIds: readonly string[], ctx: StandingContext): ReadonlyMap<string, NodeMeasuredCapacity>;