@camstack/types 1.2.319 → 1.2.320

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,10 +1,9 @@
1
1
  /**
2
- * Auto tune (D745): the static-hardware × measured-latency × demand
3
- * recommender of ONE detector family for the whole cluster, and the shapes of
4
- * its plan. See `recommend.ts`.
2
+ * Auto tune (D745, D755): the static-hardware × measured-latency recommender
3
+ * of ONE detector family for the whole cluster, sized by a capacity floor
4
+ * (no load input), and the shapes of its plan. See `recommend.ts`.
5
5
  */
6
6
  export * from './hardware-class.js';
7
7
  export * from './detector-performance.js';
8
- export * from './demand.js';
9
8
  export * from './recommend.js';
10
9
  export * from './plan-schemas.js';
@@ -1,10 +1,17 @@
1
1
  /**
2
2
  * The wire shapes of the Auto tune plan and apply (D745), used by the
3
3
  * `pipeline-orchestrator` cap. The recommender's own types
4
- * (`recommend.ts`, `demand.ts`) are the TS face of the same data; these
4
+ * (`recommend.ts`) are the TS face of the same data; these
5
5
  * schemas are what crosses the cap boundary.
6
6
  */
7
7
  import { z } from 'zod';
8
+ /** Default least number of parallel sessions per device Auto tune keeps (D755). */
9
+ export declare const DEFAULT_MIN_SESSIONS_PER_DEVICE = 2;
10
+ /** The operator's range for it. */
11
+ export declare const MIN_SESSIONS_PER_DEVICE_RANGE: {
12
+ readonly min: 1;
13
+ readonly max: 8;
14
+ };
8
15
  export declare const HardwareClassIdSchema: z.ZodEnum<{
9
16
  unknown: "unknown";
10
17
  "intel-core-ultra": "intel-core-ultra";
@@ -21,8 +28,9 @@ export declare const AcceleratorKindSchema: z.ZodEnum<{
21
28
  coral: "coral";
22
29
  }>;
23
30
  export declare const RecommendationReasonSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
24
- kind: z.ZodLiteral<"fits">;
25
- utilisation: z.ZodNumber;
31
+ kind: z.ZodLiteral<"capacity">;
32
+ sessions: z.ZodNumber;
33
+ minSessions: z.ZodNumber;
26
34
  }, z.core.$strip>, z.ZodObject<{
27
35
  kind: z.ZodLiteral<"tie-faster">;
28
36
  over: z.ZodString;
@@ -34,13 +42,11 @@ export declare const RecommendationReasonSchema: z.ZodDiscriminatedUnion<[z.ZodO
34
42
  limitedBy: z.ZodString;
35
43
  }, z.core.$strip>, z.ZodObject<{
36
44
  kind: z.ZodLiteral<"no-fit-lightest">;
37
- utilisation: z.ZodNumber;
45
+ sessions: z.ZodNumber;
46
+ minSessions: z.ZodNumber;
38
47
  }, z.core.$strip>, z.ZodObject<{
39
48
  kind: z.ZodLiteral<"derived-latency">;
40
49
  modelId: z.ZodString;
41
- }, z.core.$strip>, z.ZodObject<{
42
- kind: z.ZodLiteral<"estimated-load">;
43
- observedForMs: z.ZodNullable<z.ZodNumber>;
44
50
  }, z.core.$strip>, z.ZodObject<{
45
51
  kind: z.ZodLiteral<"cpu-device">;
46
52
  }, z.core.$strip>, z.ZodObject<{
@@ -73,30 +79,12 @@ export declare const RecommendationReasonSchema: z.ZodDiscriminatedUnion<[z.ZodO
73
79
  gguf: "gguf";
74
80
  }>;
75
81
  }, z.core.$strip>], "kind">;
76
- export declare const DeviceDemandSchema: z.ZodObject<{
77
- nodeId: z.ZodString;
78
- deviceKey: z.ZodString;
79
- demandFps: z.ZodNumber;
80
- maxCameraFps: z.ZodNumber;
81
- alwaysOnCameras: z.ZodNumber;
82
- onMotionSessions: z.ZodNumber;
83
- onMotionSource: z.ZodEnum<{
84
- none: "none";
85
- "observed-24h": "observed-24h";
86
- estimate: "estimate";
87
- }>;
88
- observedForMs: z.ZodNullable<z.ZodNumber>;
89
- placement: z.ZodEnum<{
90
- "least-loaded": "least-loaded";
91
- share: "share";
92
- }>;
93
- }, z.core.$strip>;
94
82
  export declare const DeviceModelChoiceSchema: z.ZodObject<{
95
83
  modelId: z.ZodString;
96
84
  p50Ms: z.ZodNumber;
97
85
  fps: z.ZodNumber;
98
86
  measured: z.ZodBoolean;
99
- utilisation: z.ZodNumber;
87
+ capacitySessions: z.ZodNumber;
100
88
  personRecall: z.ZodNumber;
101
89
  }, z.core.$strip>;
102
90
  export declare const DeviceRecommendationSchema: z.ZodObject<{
@@ -111,35 +99,18 @@ export declare const DeviceRecommendationSchema: z.ZodObject<{
111
99
  }>>;
112
100
  enabled: z.ZodBoolean;
113
101
  available: z.ZodBoolean;
114
- demand: z.ZodNullable<z.ZodObject<{
115
- nodeId: z.ZodString;
116
- deviceKey: z.ZodString;
117
- demandFps: z.ZodNumber;
118
- maxCameraFps: z.ZodNumber;
119
- alwaysOnCameras: z.ZodNumber;
120
- onMotionSessions: z.ZodNumber;
121
- onMotionSource: z.ZodEnum<{
122
- none: "none";
123
- "observed-24h": "observed-24h";
124
- estimate: "estimate";
125
- }>;
126
- observedForMs: z.ZodNullable<z.ZodNumber>;
127
- placement: z.ZodEnum<{
128
- "least-loaded": "least-loaded";
129
- share: "share";
130
- }>;
131
- }, z.core.$strip>>;
132
102
  chosen: z.ZodNullable<z.ZodObject<{
133
103
  modelId: z.ZodString;
134
104
  p50Ms: z.ZodNumber;
135
105
  fps: z.ZodNumber;
136
106
  measured: z.ZodBoolean;
137
- utilisation: z.ZodNumber;
107
+ capacitySessions: z.ZodNumber;
138
108
  personRecall: z.ZodNumber;
139
109
  }, z.core.$strip>>;
140
110
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
141
- kind: z.ZodLiteral<"fits">;
142
- utilisation: z.ZodNumber;
111
+ kind: z.ZodLiteral<"capacity">;
112
+ sessions: z.ZodNumber;
113
+ minSessions: z.ZodNumber;
143
114
  }, z.core.$strip>, z.ZodObject<{
144
115
  kind: z.ZodLiteral<"tie-faster">;
145
116
  over: z.ZodString;
@@ -151,13 +122,11 @@ export declare const DeviceRecommendationSchema: z.ZodObject<{
151
122
  limitedBy: z.ZodString;
152
123
  }, z.core.$strip>, z.ZodObject<{
153
124
  kind: z.ZodLiteral<"no-fit-lightest">;
154
- utilisation: z.ZodNumber;
125
+ sessions: z.ZodNumber;
126
+ minSessions: z.ZodNumber;
155
127
  }, z.core.$strip>, z.ZodObject<{
156
128
  kind: z.ZodLiteral<"derived-latency">;
157
129
  modelId: z.ZodString;
158
- }, z.core.$strip>, z.ZodObject<{
159
- kind: z.ZodLiteral<"estimated-load">;
160
- observedForMs: z.ZodNullable<z.ZodNumber>;
161
130
  }, z.core.$strip>, z.ZodObject<{
162
131
  kind: z.ZodLiteral<"cpu-device">;
163
132
  }, z.core.$strip>, z.ZodObject<{
@@ -216,35 +185,18 @@ export declare const NodeRecommendationSchema: z.ZodObject<{
216
185
  }>>;
217
186
  enabled: z.ZodBoolean;
218
187
  available: z.ZodBoolean;
219
- demand: z.ZodNullable<z.ZodObject<{
220
- nodeId: z.ZodString;
221
- deviceKey: z.ZodString;
222
- demandFps: z.ZodNumber;
223
- maxCameraFps: z.ZodNumber;
224
- alwaysOnCameras: z.ZodNumber;
225
- onMotionSessions: z.ZodNumber;
226
- onMotionSource: z.ZodEnum<{
227
- none: "none";
228
- "observed-24h": "observed-24h";
229
- estimate: "estimate";
230
- }>;
231
- observedForMs: z.ZodNullable<z.ZodNumber>;
232
- placement: z.ZodEnum<{
233
- "least-loaded": "least-loaded";
234
- share: "share";
235
- }>;
236
- }, z.core.$strip>>;
237
188
  chosen: z.ZodNullable<z.ZodObject<{
238
189
  modelId: z.ZodString;
239
190
  p50Ms: z.ZodNumber;
240
191
  fps: z.ZodNumber;
241
192
  measured: z.ZodBoolean;
242
- utilisation: z.ZodNumber;
193
+ capacitySessions: z.ZodNumber;
243
194
  personRecall: z.ZodNumber;
244
195
  }, z.core.$strip>>;
245
196
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
246
- kind: z.ZodLiteral<"fits">;
247
- utilisation: z.ZodNumber;
197
+ kind: z.ZodLiteral<"capacity">;
198
+ sessions: z.ZodNumber;
199
+ minSessions: z.ZodNumber;
248
200
  }, z.core.$strip>, z.ZodObject<{
249
201
  kind: z.ZodLiteral<"tie-faster">;
250
202
  over: z.ZodString;
@@ -256,13 +208,11 @@ export declare const NodeRecommendationSchema: z.ZodObject<{
256
208
  limitedBy: z.ZodString;
257
209
  }, z.core.$strip>, z.ZodObject<{
258
210
  kind: z.ZodLiteral<"no-fit-lightest">;
259
- utilisation: z.ZodNumber;
211
+ sessions: z.ZodNumber;
212
+ minSessions: z.ZodNumber;
260
213
  }, z.core.$strip>, z.ZodObject<{
261
214
  kind: z.ZodLiteral<"derived-latency">;
262
215
  modelId: z.ZodString;
263
- }, z.core.$strip>, z.ZodObject<{
264
- kind: z.ZodLiteral<"estimated-load">;
265
- observedForMs: z.ZodNullable<z.ZodNumber>;
266
216
  }, z.core.$strip>, z.ZodObject<{
267
217
  kind: z.ZodLiteral<"cpu-device">;
268
218
  }, z.core.$strip>, z.ZodObject<{
@@ -297,8 +247,9 @@ export declare const NodeRecommendationSchema: z.ZodObject<{
297
247
  }, z.core.$strip>], "kind">>>;
298
248
  }, z.core.$strip>>>;
299
249
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
300
- kind: z.ZodLiteral<"fits">;
301
- utilisation: z.ZodNumber;
250
+ kind: z.ZodLiteral<"capacity">;
251
+ sessions: z.ZodNumber;
252
+ minSessions: z.ZodNumber;
302
253
  }, z.core.$strip>, z.ZodObject<{
303
254
  kind: z.ZodLiteral<"tie-faster">;
304
255
  over: z.ZodString;
@@ -310,13 +261,11 @@ export declare const NodeRecommendationSchema: z.ZodObject<{
310
261
  limitedBy: z.ZodString;
311
262
  }, z.core.$strip>, z.ZodObject<{
312
263
  kind: z.ZodLiteral<"no-fit-lightest">;
313
- utilisation: z.ZodNumber;
264
+ sessions: z.ZodNumber;
265
+ minSessions: z.ZodNumber;
314
266
  }, z.core.$strip>, z.ZodObject<{
315
267
  kind: z.ZodLiteral<"derived-latency">;
316
268
  modelId: z.ZodString;
317
- }, z.core.$strip>, z.ZodObject<{
318
- kind: z.ZodLiteral<"estimated-load">;
319
- observedForMs: z.ZodNullable<z.ZodNumber>;
320
269
  }, z.core.$strip>, z.ZodObject<{
321
270
  kind: z.ZodLiteral<"cpu-device">;
322
271
  }, z.core.$strip>, z.ZodObject<{
@@ -398,16 +347,14 @@ export declare const AutoTuneWarningSchema: z.ZodDiscriminatedUnion<[z.ZodObject
398
347
  }, z.core.$strip>], "kind">;
399
348
  export declare const AutoTuneOptionsSchema: z.ZodObject<{
400
349
  headroom: z.ZodDefault<z.ZodNumber>;
401
- shares: z.ZodOptional<z.ZodObject<{
402
- nodes: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNumber>>;
403
- devices: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodNumber>>>;
404
- }, z.core.$strip>>;
350
+ minSessionsPerDevice: z.ZodDefault<z.ZodNumber>;
405
351
  }, z.core.$strip>;
406
352
  export declare const AutoTunePlanSchema: z.ZodObject<{
407
353
  planHash: z.ZodString;
408
354
  family: z.ZodLiteral<"yolov9">;
409
355
  headroom: z.ZodNumber;
410
- whatIf: z.ZodBoolean;
356
+ minSessionsPerDevice: z.ZodNumber;
357
+ cameraFps: z.ZodNumber;
411
358
  generatedAt: z.ZodNumber;
412
359
  nodes: z.ZodReadonly<z.ZodArray<z.ZodObject<{
413
360
  nodeId: z.ZodString;
@@ -434,35 +381,18 @@ export declare const AutoTunePlanSchema: z.ZodObject<{
434
381
  }>>;
435
382
  enabled: z.ZodBoolean;
436
383
  available: z.ZodBoolean;
437
- demand: z.ZodNullable<z.ZodObject<{
438
- nodeId: z.ZodString;
439
- deviceKey: z.ZodString;
440
- demandFps: z.ZodNumber;
441
- maxCameraFps: z.ZodNumber;
442
- alwaysOnCameras: z.ZodNumber;
443
- onMotionSessions: z.ZodNumber;
444
- onMotionSource: z.ZodEnum<{
445
- none: "none";
446
- "observed-24h": "observed-24h";
447
- estimate: "estimate";
448
- }>;
449
- observedForMs: z.ZodNullable<z.ZodNumber>;
450
- placement: z.ZodEnum<{
451
- "least-loaded": "least-loaded";
452
- share: "share";
453
- }>;
454
- }, z.core.$strip>>;
455
384
  chosen: z.ZodNullable<z.ZodObject<{
456
385
  modelId: z.ZodString;
457
386
  p50Ms: z.ZodNumber;
458
387
  fps: z.ZodNumber;
459
388
  measured: z.ZodBoolean;
460
- utilisation: z.ZodNumber;
389
+ capacitySessions: z.ZodNumber;
461
390
  personRecall: z.ZodNumber;
462
391
  }, z.core.$strip>>;
463
392
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
464
- kind: z.ZodLiteral<"fits">;
465
- utilisation: z.ZodNumber;
393
+ kind: z.ZodLiteral<"capacity">;
394
+ sessions: z.ZodNumber;
395
+ minSessions: z.ZodNumber;
466
396
  }, z.core.$strip>, z.ZodObject<{
467
397
  kind: z.ZodLiteral<"tie-faster">;
468
398
  over: z.ZodString;
@@ -474,13 +404,11 @@ export declare const AutoTunePlanSchema: z.ZodObject<{
474
404
  limitedBy: z.ZodString;
475
405
  }, z.core.$strip>, z.ZodObject<{
476
406
  kind: z.ZodLiteral<"no-fit-lightest">;
477
- utilisation: z.ZodNumber;
407
+ sessions: z.ZodNumber;
408
+ minSessions: z.ZodNumber;
478
409
  }, z.core.$strip>, z.ZodObject<{
479
410
  kind: z.ZodLiteral<"derived-latency">;
480
411
  modelId: z.ZodString;
481
- }, z.core.$strip>, z.ZodObject<{
482
- kind: z.ZodLiteral<"estimated-load">;
483
- observedForMs: z.ZodNullable<z.ZodNumber>;
484
412
  }, z.core.$strip>, z.ZodObject<{
485
413
  kind: z.ZodLiteral<"cpu-device">;
486
414
  }, z.core.$strip>, z.ZodObject<{
@@ -515,8 +443,9 @@ export declare const AutoTunePlanSchema: z.ZodObject<{
515
443
  }, z.core.$strip>], "kind">>>;
516
444
  }, z.core.$strip>>>;
517
445
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
518
- kind: z.ZodLiteral<"fits">;
519
- utilisation: z.ZodNumber;
446
+ kind: z.ZodLiteral<"capacity">;
447
+ sessions: z.ZodNumber;
448
+ minSessions: z.ZodNumber;
520
449
  }, z.core.$strip>, z.ZodObject<{
521
450
  kind: z.ZodLiteral<"tie-faster">;
522
451
  over: z.ZodString;
@@ -528,13 +457,11 @@ export declare const AutoTunePlanSchema: z.ZodObject<{
528
457
  limitedBy: z.ZodString;
529
458
  }, z.core.$strip>, z.ZodObject<{
530
459
  kind: z.ZodLiteral<"no-fit-lightest">;
531
- utilisation: z.ZodNumber;
460
+ sessions: z.ZodNumber;
461
+ minSessions: z.ZodNumber;
532
462
  }, z.core.$strip>, z.ZodObject<{
533
463
  kind: z.ZodLiteral<"derived-latency">;
534
464
  modelId: z.ZodString;
535
- }, z.core.$strip>, z.ZodObject<{
536
- kind: z.ZodLiteral<"estimated-load">;
537
- observedForMs: z.ZodNullable<z.ZodNumber>;
538
465
  }, z.core.$strip>, z.ZodObject<{
539
466
  kind: z.ZodLiteral<"cpu-device">;
540
467
  }, z.core.$strip>, z.ZodObject<{
@@ -613,6 +540,7 @@ export declare const AutoTunePlanSchema: z.ZodObject<{
613
540
  export declare const AutoTuneApplyInputSchema: z.ZodObject<{
614
541
  planHash: z.ZodString;
615
542
  headroom: z.ZodDefault<z.ZodNumber>;
543
+ minSessionsPerDevice: z.ZodDefault<z.ZodNumber>;
616
544
  }, z.core.$strip>;
617
545
  export declare const AutoTunePhaseResultSchema: z.ZodObject<{
618
546
  phase: z.ZodEnum<{
@@ -658,7 +586,8 @@ export declare const AutoTuneApplyResultSchema: z.ZodDiscriminatedUnion<[z.ZodOb
658
586
  planHash: z.ZodString;
659
587
  family: z.ZodLiteral<"yolov9">;
660
588
  headroom: z.ZodNumber;
661
- whatIf: z.ZodBoolean;
589
+ minSessionsPerDevice: z.ZodNumber;
590
+ cameraFps: z.ZodNumber;
662
591
  generatedAt: z.ZodNumber;
663
592
  nodes: z.ZodReadonly<z.ZodArray<z.ZodObject<{
664
593
  nodeId: z.ZodString;
@@ -685,35 +614,18 @@ export declare const AutoTuneApplyResultSchema: z.ZodDiscriminatedUnion<[z.ZodOb
685
614
  }>>;
686
615
  enabled: z.ZodBoolean;
687
616
  available: z.ZodBoolean;
688
- demand: z.ZodNullable<z.ZodObject<{
689
- nodeId: z.ZodString;
690
- deviceKey: z.ZodString;
691
- demandFps: z.ZodNumber;
692
- maxCameraFps: z.ZodNumber;
693
- alwaysOnCameras: z.ZodNumber;
694
- onMotionSessions: z.ZodNumber;
695
- onMotionSource: z.ZodEnum<{
696
- none: "none";
697
- "observed-24h": "observed-24h";
698
- estimate: "estimate";
699
- }>;
700
- observedForMs: z.ZodNullable<z.ZodNumber>;
701
- placement: z.ZodEnum<{
702
- "least-loaded": "least-loaded";
703
- share: "share";
704
- }>;
705
- }, z.core.$strip>>;
706
617
  chosen: z.ZodNullable<z.ZodObject<{
707
618
  modelId: z.ZodString;
708
619
  p50Ms: z.ZodNumber;
709
620
  fps: z.ZodNumber;
710
621
  measured: z.ZodBoolean;
711
- utilisation: z.ZodNumber;
622
+ capacitySessions: z.ZodNumber;
712
623
  personRecall: z.ZodNumber;
713
624
  }, z.core.$strip>>;
714
625
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
715
- kind: z.ZodLiteral<"fits">;
716
- utilisation: z.ZodNumber;
626
+ kind: z.ZodLiteral<"capacity">;
627
+ sessions: z.ZodNumber;
628
+ minSessions: z.ZodNumber;
717
629
  }, z.core.$strip>, z.ZodObject<{
718
630
  kind: z.ZodLiteral<"tie-faster">;
719
631
  over: z.ZodString;
@@ -725,13 +637,11 @@ export declare const AutoTuneApplyResultSchema: z.ZodDiscriminatedUnion<[z.ZodOb
725
637
  limitedBy: z.ZodString;
726
638
  }, z.core.$strip>, z.ZodObject<{
727
639
  kind: z.ZodLiteral<"no-fit-lightest">;
728
- utilisation: z.ZodNumber;
640
+ sessions: z.ZodNumber;
641
+ minSessions: z.ZodNumber;
729
642
  }, z.core.$strip>, z.ZodObject<{
730
643
  kind: z.ZodLiteral<"derived-latency">;
731
644
  modelId: z.ZodString;
732
- }, z.core.$strip>, z.ZodObject<{
733
- kind: z.ZodLiteral<"estimated-load">;
734
- observedForMs: z.ZodNullable<z.ZodNumber>;
735
645
  }, z.core.$strip>, z.ZodObject<{
736
646
  kind: z.ZodLiteral<"cpu-device">;
737
647
  }, z.core.$strip>, z.ZodObject<{
@@ -766,8 +676,9 @@ export declare const AutoTuneApplyResultSchema: z.ZodDiscriminatedUnion<[z.ZodOb
766
676
  }, z.core.$strip>], "kind">>>;
767
677
  }, z.core.$strip>>>;
768
678
  reasons: z.ZodReadonly<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
769
- kind: z.ZodLiteral<"fits">;
770
- utilisation: z.ZodNumber;
679
+ kind: z.ZodLiteral<"capacity">;
680
+ sessions: z.ZodNumber;
681
+ minSessions: z.ZodNumber;
771
682
  }, z.core.$strip>, z.ZodObject<{
772
683
  kind: z.ZodLiteral<"tie-faster">;
773
684
  over: z.ZodString;
@@ -779,13 +690,11 @@ export declare const AutoTuneApplyResultSchema: z.ZodDiscriminatedUnion<[z.ZodOb
779
690
  limitedBy: z.ZodString;
780
691
  }, z.core.$strip>, z.ZodObject<{
781
692
  kind: z.ZodLiteral<"no-fit-lightest">;
782
- utilisation: z.ZodNumber;
693
+ sessions: z.ZodNumber;
694
+ minSessions: z.ZodNumber;
783
695
  }, z.core.$strip>, z.ZodObject<{
784
696
  kind: z.ZodLiteral<"derived-latency">;
785
697
  modelId: z.ZodString;
786
- }, z.core.$strip>, z.ZodObject<{
787
- kind: z.ZodLiteral<"estimated-load">;
788
- observedForMs: z.ZodNullable<z.ZodNumber>;
789
698
  }, z.core.$strip>, z.ZodObject<{
790
699
  kind: z.ZodLiteral<"cpu-device">;
791
700
  }, z.core.$strip>, z.ZodObject<{
@@ -879,7 +788,6 @@ export type AutoTuneNodeDeviceChange = z.infer<typeof NodeDeviceChangeSchema>;
879
788
  export type HardwareClassId = z.infer<typeof HardwareClassIdSchema>;
880
789
  export type AcceleratorKind = z.infer<typeof AcceleratorKindSchema>;
881
790
  export type RecommendationReason = z.infer<typeof RecommendationReasonSchema>;
882
- export type DeviceDemand = z.infer<typeof DeviceDemandSchema>;
883
791
  export type DeviceModelChoice = z.infer<typeof DeviceModelChoiceSchema>;
884
792
  export type DeviceRecommendation = z.infer<typeof DeviceRecommendationSchema>;
885
793
  export type NodeRecommendation = z.infer<typeof NodeRecommendationSchema>;
@@ -1,7 +1,8 @@
1
1
  /**
2
- * The Auto tune recommender (D745): one detector per node, from ONE family
3
- * (YOLOv9) for the whole cluster, chosen from static hardware facts × the
4
- * measured latency table × the node's detection demand. Pure; no benchmark.
2
+ * The Auto tune recommender (D745, D755): one detector per node, from ONE
3
+ * family (YOLOv9) for the whole cluster, chosen from static hardware facts ×
4
+ * the measured latency table × a capacity floor. Pure; no benchmark, and no
5
+ * load: nothing here depends on how many sessions ran yesterday.
5
6
  *
6
7
  * Per node:
7
8
  * 1. Classify the hardware (`classifyInferenceHardware`). An unknown class,
@@ -10,25 +11,31 @@
10
11
  * available share ONE model — so a camera's floors never flip with the
11
12
  * device the balancer rotated it onto. A candidate must have a build for
12
13
  * every accelerator's format and a latency cell for each.
13
- * 3. A candidate FITS a device when its throughput, less the headroom, covers
14
- * the device's demand and the single fastest camera that can land on it.
14
+ * 3. A candidate FITS a device when the device sustains at least
15
+ * `minSessionsPerDevice` parallel sessions with it:
16
+ * ⌊fps × (1 − headroom) / camera fps⌋ ≥ minSessionsPerDevice.
15
17
  * 4. Among candidates that fit everywhere, the most accurate wins (person
16
18
  * recall at the shipped floor); within `RECALL_TIE` of the best, the
17
19
  * fastest wins. That IS the step-down order the data gives: the first
18
- * variant down from m-640 is s-640-int8, not m-320.
20
+ * variant down from m-640 is s-640-int8, not m-320. When nothing fits,
21
+ * the candidate with the most capacity is used and the plan says so.
19
22
  * 5. An enabled CPU device (the fallback pool) gets its own pick the same
20
23
  * way; a Coral is never touched (no YOLOv9 build), only reported.
21
24
  */
22
25
  import type { HardwareInfo } from '../../interfaces/platform.js';
23
26
  import type { ModelFormat } from '../../types/models.js';
24
27
  import { type DetectorPerfTable } from './detector-performance.js';
25
- import type { DeviceDemand, NodeRecommendation } from './plan-schemas.js';
28
+ import { type NodeRecommendation } from './plan-schemas.js';
26
29
  /** The family the cluster runs. */
27
30
  export declare const AUTO_TUNE_FAMILY = "yolov9";
28
31
  /** Recall within this of the best counts as a tie — the faster one wins. */
29
32
  export declare const RECALL_TIE = 0.02;
30
33
  /** Default share of an accelerator's throughput kept free. */
31
34
  export declare const DEFAULT_HEADROOM = 0.4;
35
+ /** Detection rate a session is counted at when no camera says otherwise. */
36
+ export declare const DEFAULT_CAMERA_FPS = 10;
37
+ /** Parallel sessions one device sustains at `fps` with `headroom` kept free. */
38
+ export declare function capacitySessionsOf(fps: number, headroom: number, cameraFps: number): number;
32
39
  /** One device of a node, as the recommender reads it. */
33
40
  export interface AutoTuneDeviceInput {
34
41
  readonly key: string;
@@ -48,7 +55,10 @@ export interface AutoTuneNodeInput {
48
55
  /** Recommend one node. See the module header. */
49
56
  export declare function recommendNode(input: {
50
57
  readonly node: AutoTuneNodeInput;
51
- readonly demand: readonly DeviceDemand[];
52
58
  readonly headroom?: number;
59
+ /** Least parallel sessions per device (default {@link DEFAULT_MIN_SESSIONS_PER_DEVICE}). */
60
+ readonly minSessionsPerDevice?: number;
61
+ /** The rate a session is counted at (default {@link DEFAULT_CAMERA_FPS}). */
62
+ readonly cameraFps?: number;
53
63
  readonly perf?: DetectorPerfTable;
54
64
  }): NodeRecommendation;
@@ -0,0 +1,37 @@
1
+ import type { NodeRecommendation } from '../auto-tune/plan-schemas.js';
2
+ import type { CapacitySource, SuggestSharesResult } from './schemas.js';
3
+ /** One device's measured capacity (a node benchmark result, reduced to what shares need). */
4
+ export interface DeviceMeasuredCapacity {
5
+ readonly deviceKey: string;
6
+ /** Parallel sessions the device sustained at the camera rate. */
7
+ readonly maxSessions: number;
8
+ readonly modelId: string | null;
9
+ readonly measuredAtMs: number;
10
+ }
11
+ /** One node's measured capacity. */
12
+ export interface NodeMeasuredCapacity {
13
+ readonly nodeId: string;
14
+ readonly devices: readonly DeviceMeasuredCapacity[];
15
+ }
16
+ /**
17
+ * Where measured node capacity is read from. The node-benchmark results
18
+ * store implements it; until it exists the orchestrator wires one that
19
+ * answers nothing, and every node falls back to `hardware`.
20
+ */
21
+ export interface NodeCapacitySource {
22
+ /** The usable (fresh) measured capacity of each asked node that has any. */
23
+ readMeasuredCapacity(nodeIds: readonly string[]): Promise<ReadonlyMap<string, NodeMeasuredCapacity>>;
24
+ }
25
+ /** A source that has no results — the benchmark store before it exists. */
26
+ export declare const NO_MEASURED_CAPACITY: NodeCapacitySource;
27
+ /** Integer shares summing to 100 (largest remainder); ties broken by key. */
28
+ export declare function toPercentShares(weights: ReadonlyMap<string, number>): Map<string, number>;
29
+ /** Shares proportional to capacity — the automatic shares and the suggestion are this. */
30
+ export declare function computeCapacityShares(input: {
31
+ readonly recommendations: readonly NodeRecommendation[];
32
+ readonly source: CapacitySource;
33
+ readonly measured: ReadonlyMap<string, NodeMeasuredCapacity>;
34
+ readonly headroom: number;
35
+ readonly cameraFps: number;
36
+ readonly minSessionsPerDevice: number;
37
+ }): SuggestSharesResult;
@@ -2,15 +2,15 @@
2
2
  * The shares a session election actually reads, and the view the Load
3
3
  * balancing tab shows (D750). Pure.
4
4
  *
5
- * The SOURCE decides the configured weights: the automatic capacity shares,
6
- * or the operator's stored sliders. Eligibility decides the effective ones: a
5
+ * The SOURCE decides the configured weights: the automatic capacity shares
6
+ * (`hardware` or `benchmark`, D755), or the operator's stored sliders. Eligibility decides the effective ones: a
7
7
  * node or device that cannot take a session now (offline, switched off, no
8
8
  * detect capability, unable to run the root) contributes nothing, and the
9
9
  * others split its share in proportion to their own. That redistribution is
10
10
  * exactly what `electByShare` does over its candidate set, so the view and
11
11
  * the election cannot disagree; the stored values are never rewritten for it.
12
12
  */
13
- import type { EffectiveShares, SessionPlacementPolicy, ShareSource, ShareWeights } from './schemas.js';
13
+ import { type CapacityFallback, type CapacitySource, type EffectiveShares, type SessionPlacementPolicy, type ShareSource, type ShareWeights } from './schemas.js';
14
14
  export interface EffectiveSharesInput {
15
15
  readonly source: ShareSource;
16
16
  /** Every node the view covers, eligible or not. */
@@ -18,6 +18,11 @@ export interface EffectiveSharesInput {
18
18
  readonly stored: ShareWeights;
19
19
  /** The last automatic computation; null = none yet. */
20
20
  readonly auto: ShareWeights | null;
21
+ /** Per node, what the automatic answer was computed from. */
22
+ readonly autoCapacity?: Readonly<Record<string, {
23
+ readonly source: CapacitySource;
24
+ readonly fallback: CapacityFallback | null;
25
+ }>>;
21
26
  readonly eligibleNodes: readonly string[];
22
27
  /** nodeId → device keys that can take sessions; a node absent here lists none. */
23
28
  readonly eligibleDevices: Readonly<Record<string, readonly string[]>>;
@@ -1,8 +1,9 @@
1
1
  /**
2
- * Load balancing (D748, D750): the share placement policy for detection
2
+ * Load balancing (D748, D750, D755): the share placement policy for detection
3
3
  * sessions, where its shares come from, and the shapes of its admin surface.
4
- * See `share-election.ts` and `effective-shares.ts`.
4
+ * See `share-election.ts`, `effective-shares.ts` and `capacity-shares.ts`.
5
5
  */
6
6
  export * from './share-election.js';
7
7
  export * from './schemas.js';
8
8
  export * from './effective-shares.js';
9
+ export * from './capacity-shares.js';