@camstack/types 1.2.317 → 1.2.319
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.
- package/dist/addon.js +9 -3
- package/dist/addon.mjs +9 -3
- package/dist/capabilities/pipeline-executor.cap.d.ts +1 -1
- package/dist/capabilities/pipeline-orchestrator.cap.d.ts +146 -16
- package/dist/client.js +7 -3
- package/dist/client.mjs +7 -3
- package/dist/generated/addon-api.d.ts +41 -13
- package/dist/generated/cap-input-defaults.d.ts +1 -1
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/system-proxy.d.ts +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +438 -65
- package/dist/index.mjs +406 -59
- package/dist/pipeline/{best-settings → auto-tune}/demand.d.ts +27 -30
- package/dist/pipeline/{best-settings → auto-tune}/hardware-class.d.ts +1 -1
- package/dist/pipeline/{best-settings → auto-tune}/index.d.ts +1 -1
- package/dist/pipeline/{best-settings → auto-tune}/plan-schemas.d.ts +41 -15
- package/dist/pipeline/{best-settings → auto-tune}/recommend.d.ts +6 -6
- package/dist/pipeline/load-balancing/effective-shares.d.ts +28 -0
- package/dist/pipeline/load-balancing/index.d.ts +8 -0
- package/dist/pipeline/load-balancing/schemas.d.ts +232 -0
- package/dist/pipeline/load-balancing/share-election.d.ts +54 -0
- package/dist/pipeline/model-bound-settings.d.ts +1 -1
- package/dist/types/agent-pipeline-settings.d.ts +0 -1
- package/package.json +1 -1
- /package/dist/pipeline/{best-settings → auto-tune}/detector-performance.d.ts +0 -0
|
@@ -1,46 +1,41 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Detection demand per inference device, for the Best settings recommender
|
|
3
|
-
* (D745). Pure.
|
|
4
|
-
*
|
|
5
|
-
* Demand is inferences per second a device must sustain:
|
|
6
|
-
*
|
|
7
|
-
* - a camera PINNED to a device charges its full rate to that device;
|
|
8
|
-
* - an ALWAYS-ON camera charges its rate to its standing node, split over
|
|
9
|
-
* that node's eligible devices by balancer weight (the device tier rotates
|
|
10
|
-
* ties, so the weight share is the long-run split);
|
|
11
|
-
* - ON-MOTION cameras are placed per session anywhere in the cluster, so
|
|
12
|
-
* they are charged by how many sessions a device has really carried at
|
|
13
|
-
* once: the observed 24 h peak of attached sessions on that device, minus
|
|
14
|
-
* the always-on cameras it already counts, filled with the highest
|
|
15
|
-
* on-motion rates. A device observed for less than 24 h (the hub
|
|
16
|
-
* restarted) falls back to a fixed estimate — a quarter of the on-motion
|
|
17
|
-
* cameras, at least two, spread evenly over the nodes and by weight over a
|
|
18
|
-
* node's devices — and the plan says so.
|
|
19
|
-
*
|
|
20
|
-
* Every device must also fit the single fastest camera that can land on it:
|
|
21
|
-
* one session cannot be split across devices.
|
|
22
|
-
*/
|
|
23
1
|
import type { DeviceDemand } from './plan-schemas.js';
|
|
24
2
|
/** How a camera's detection runs. `disabled` cameras charge nothing. */
|
|
25
|
-
export type
|
|
3
|
+
export type AutoTuneDetectionMode = 'always-on' | 'on-motion' | 'disabled';
|
|
26
4
|
/** One camera's detection load. */
|
|
27
|
-
export interface
|
|
5
|
+
export interface AutoTuneCameraLoad {
|
|
28
6
|
readonly deviceId: number;
|
|
29
|
-
readonly mode:
|
|
7
|
+
readonly mode: AutoTuneDetectionMode;
|
|
30
8
|
/** Detection frames per second while a session runs. */
|
|
31
9
|
readonly fps: number;
|
|
32
10
|
/** False when only the camera's own (onboard) detector runs — no pipeline root. */
|
|
33
11
|
readonly runsPipelineRoot: boolean;
|
|
34
12
|
/** The node an always-on camera stands on; null when not placed (on-motion). */
|
|
35
13
|
readonly standingNodeId: string | null;
|
|
36
|
-
/**
|
|
14
|
+
/** The operator's node pin (`pipelineNodeId`), or null. */
|
|
15
|
+
readonly nodePinId: string | null;
|
|
16
|
+
/**
|
|
17
|
+
* An operator pin of this camera to one device. `nodeId` null = the pin
|
|
18
|
+
* names only a deviceKey (no node pin, no standing node): it resolves to the
|
|
19
|
+
* one node that has that key, or is ignored when several or none do.
|
|
20
|
+
*/
|
|
37
21
|
readonly devicePin: {
|
|
38
|
-
readonly nodeId: string;
|
|
22
|
+
readonly nodeId: string | null;
|
|
39
23
|
readonly deviceKey: string;
|
|
40
24
|
} | null;
|
|
41
25
|
}
|
|
26
|
+
/** The cluster-wide peak of parallel sessions (sum over every device at one census). */
|
|
27
|
+
export interface ObservedClusterPeak {
|
|
28
|
+
readonly peakSessions: number;
|
|
29
|
+
readonly observedForMs: number;
|
|
30
|
+
}
|
|
31
|
+
/** Share placement input: node shares and the cluster-wide peak. */
|
|
32
|
+
export interface DemandShares {
|
|
33
|
+
/** nodeId → share (any scale). Device shares are the eligible devices' weights. */
|
|
34
|
+
readonly nodes: Readonly<Record<string, number>>;
|
|
35
|
+
readonly clusterPeak: ObservedClusterPeak | null;
|
|
36
|
+
}
|
|
42
37
|
/** A device the balancer may place a session on. */
|
|
43
|
-
export interface
|
|
38
|
+
export interface AutoTuneEligibleDevice {
|
|
44
39
|
readonly nodeId: string;
|
|
45
40
|
readonly deviceKey: string;
|
|
46
41
|
readonly weight: number;
|
|
@@ -71,8 +66,10 @@ export declare function estimatedConcurrentSessions(cameraCount: number, options
|
|
|
71
66
|
* Demand on every eligible device of the cluster.
|
|
72
67
|
*/
|
|
73
68
|
export declare function estimateDeviceDemand(input: {
|
|
74
|
-
readonly cameras: readonly
|
|
75
|
-
readonly eligible: readonly
|
|
69
|
+
readonly cameras: readonly AutoTuneCameraLoad[];
|
|
70
|
+
readonly eligible: readonly AutoTuneEligibleDevice[];
|
|
76
71
|
readonly peaks: readonly ObservedDevicePeak[];
|
|
77
72
|
readonly options?: DemandOptions;
|
|
73
|
+
/** Present ⇒ share placement (D748); absent ⇒ least-loaded. */
|
|
74
|
+
readonly shares?: DemandShares;
|
|
78
75
|
}): readonly DeviceDemand[];
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Static hardware classification for the
|
|
2
|
+
* Static hardware classification for the Auto tune recommender (D745).
|
|
3
3
|
*
|
|
4
4
|
* A node is classified from the facts its platform probe already reports —
|
|
5
5
|
* `cpuModel`, `arch`, `gpu`, `npu` — never from a benchmark. The class picks a
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The wire shapes of the
|
|
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
4
|
* (`recommend.ts`, `demand.ts`) are the TS face of the same data; these
|
|
5
5
|
* schemas are what crosses the cap boundary.
|
|
@@ -86,6 +86,10 @@ export declare const DeviceDemandSchema: z.ZodObject<{
|
|
|
86
86
|
estimate: "estimate";
|
|
87
87
|
}>;
|
|
88
88
|
observedForMs: z.ZodNullable<z.ZodNumber>;
|
|
89
|
+
placement: z.ZodEnum<{
|
|
90
|
+
"least-loaded": "least-loaded";
|
|
91
|
+
share: "share";
|
|
92
|
+
}>;
|
|
89
93
|
}, z.core.$strip>;
|
|
90
94
|
export declare const DeviceModelChoiceSchema: z.ZodObject<{
|
|
91
95
|
modelId: z.ZodString;
|
|
@@ -120,6 +124,10 @@ export declare const DeviceRecommendationSchema: z.ZodObject<{
|
|
|
120
124
|
estimate: "estimate";
|
|
121
125
|
}>;
|
|
122
126
|
observedForMs: z.ZodNullable<z.ZodNumber>;
|
|
127
|
+
placement: z.ZodEnum<{
|
|
128
|
+
"least-loaded": "least-loaded";
|
|
129
|
+
share: "share";
|
|
130
|
+
}>;
|
|
123
131
|
}, z.core.$strip>>;
|
|
124
132
|
chosen: z.ZodNullable<z.ZodObject<{
|
|
125
133
|
modelId: z.ZodString;
|
|
@@ -221,6 +229,10 @@ export declare const NodeRecommendationSchema: z.ZodObject<{
|
|
|
221
229
|
estimate: "estimate";
|
|
222
230
|
}>;
|
|
223
231
|
observedForMs: z.ZodNullable<z.ZodNumber>;
|
|
232
|
+
placement: z.ZodEnum<{
|
|
233
|
+
"least-loaded": "least-loaded";
|
|
234
|
+
share: "share";
|
|
235
|
+
}>;
|
|
224
236
|
}, z.core.$strip>>;
|
|
225
237
|
chosen: z.ZodNullable<z.ZodObject<{
|
|
226
238
|
modelId: z.ZodString;
|
|
@@ -373,7 +385,7 @@ export declare const DetectorStoreClearSchema: z.ZodObject<{
|
|
|
373
385
|
deviceId: z.ZodNumber;
|
|
374
386
|
keys: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
375
387
|
}, z.core.$strip>;
|
|
376
|
-
export declare const
|
|
388
|
+
export declare const AutoTuneWarningSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
377
389
|
kind: z.ZodLiteral<"detector-store-cluster-wide">;
|
|
378
390
|
skippedNodes: z.ZodReadonly<z.ZodArray<z.ZodString>>;
|
|
379
391
|
}, z.core.$strip>, z.ZodObject<{
|
|
@@ -384,13 +396,18 @@ export declare const BestSettingsWarningSchema: z.ZodDiscriminatedUnion<[z.ZodOb
|
|
|
384
396
|
nodeId: z.ZodString;
|
|
385
397
|
deviceKey: z.ZodString;
|
|
386
398
|
}, z.core.$strip>], "kind">;
|
|
387
|
-
export declare const
|
|
399
|
+
export declare const AutoTuneOptionsSchema: z.ZodObject<{
|
|
388
400
|
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>>;
|
|
389
405
|
}, z.core.$strip>;
|
|
390
|
-
export declare const
|
|
406
|
+
export declare const AutoTunePlanSchema: z.ZodObject<{
|
|
391
407
|
planHash: z.ZodString;
|
|
392
408
|
family: z.ZodLiteral<"yolov9">;
|
|
393
409
|
headroom: z.ZodNumber;
|
|
410
|
+
whatIf: z.ZodBoolean;
|
|
394
411
|
generatedAt: z.ZodNumber;
|
|
395
412
|
nodes: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
396
413
|
nodeId: z.ZodString;
|
|
@@ -430,6 +447,10 @@ export declare const BestSettingsPlanSchema: z.ZodObject<{
|
|
|
430
447
|
estimate: "estimate";
|
|
431
448
|
}>;
|
|
432
449
|
observedForMs: z.ZodNullable<z.ZodNumber>;
|
|
450
|
+
placement: z.ZodEnum<{
|
|
451
|
+
"least-loaded": "least-loaded";
|
|
452
|
+
share: "share";
|
|
453
|
+
}>;
|
|
433
454
|
}, z.core.$strip>>;
|
|
434
455
|
chosen: z.ZodNullable<z.ZodObject<{
|
|
435
456
|
modelId: z.ZodString;
|
|
@@ -589,11 +610,11 @@ export declare const BestSettingsPlanSchema: z.ZodObject<{
|
|
|
589
610
|
deviceKey: z.ZodString;
|
|
590
611
|
}, z.core.$strip>], "kind">>>;
|
|
591
612
|
}, z.core.$strip>;
|
|
592
|
-
export declare const
|
|
613
|
+
export declare const AutoTuneApplyInputSchema: z.ZodObject<{
|
|
593
614
|
planHash: z.ZodString;
|
|
594
615
|
headroom: z.ZodDefault<z.ZodNumber>;
|
|
595
616
|
}, z.core.$strip>;
|
|
596
|
-
export declare const
|
|
617
|
+
export declare const AutoTunePhaseResultSchema: z.ZodObject<{
|
|
597
618
|
phase: z.ZodEnum<{
|
|
598
619
|
download: "download";
|
|
599
620
|
"camera-overrides": "camera-overrides";
|
|
@@ -604,7 +625,7 @@ export declare const BestSettingsPhaseResultSchema: z.ZodObject<{
|
|
|
604
625
|
ok: z.ZodBoolean;
|
|
605
626
|
detail: z.ZodString;
|
|
606
627
|
}, z.core.$strip>;
|
|
607
|
-
export declare const
|
|
628
|
+
export declare const AutoTuneApplyResultSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
608
629
|
kind: z.ZodLiteral<"applied">;
|
|
609
630
|
planHash: z.ZodString;
|
|
610
631
|
phases: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
@@ -637,6 +658,7 @@ export declare const BestSettingsApplyResultSchema: z.ZodDiscriminatedUnion<[z.Z
|
|
|
637
658
|
planHash: z.ZodString;
|
|
638
659
|
family: z.ZodLiteral<"yolov9">;
|
|
639
660
|
headroom: z.ZodNumber;
|
|
661
|
+
whatIf: z.ZodBoolean;
|
|
640
662
|
generatedAt: z.ZodNumber;
|
|
641
663
|
nodes: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
642
664
|
nodeId: z.ZodString;
|
|
@@ -676,6 +698,10 @@ export declare const BestSettingsApplyResultSchema: z.ZodDiscriminatedUnion<[z.Z
|
|
|
676
698
|
estimate: "estimate";
|
|
677
699
|
}>;
|
|
678
700
|
observedForMs: z.ZodNullable<z.ZodNumber>;
|
|
701
|
+
placement: z.ZodEnum<{
|
|
702
|
+
"least-loaded": "least-loaded";
|
|
703
|
+
share: "share";
|
|
704
|
+
}>;
|
|
679
705
|
}, z.core.$strip>>;
|
|
680
706
|
chosen: z.ZodNullable<z.ZodObject<{
|
|
681
707
|
modelId: z.ZodString;
|
|
@@ -841,15 +867,15 @@ export declare const BestSettingsApplyResultSchema: z.ZodDiscriminatedUnion<[z.Z
|
|
|
841
867
|
"apply-in-progress": "apply-in-progress";
|
|
842
868
|
}>;
|
|
843
869
|
}, z.core.$strip>], "kind">;
|
|
844
|
-
export type
|
|
845
|
-
export type
|
|
846
|
-
export type
|
|
847
|
-
export type
|
|
848
|
-
export type
|
|
849
|
-
export type
|
|
870
|
+
export type AutoTunePlan = z.infer<typeof AutoTunePlanSchema>;
|
|
871
|
+
export type AutoTuneOptions = z.infer<typeof AutoTuneOptionsSchema>;
|
|
872
|
+
export type AutoTuneApplyInput = z.infer<typeof AutoTuneApplyInputSchema>;
|
|
873
|
+
export type AutoTuneApplyResult = z.infer<typeof AutoTuneApplyResultSchema>;
|
|
874
|
+
export type AutoTunePhaseResult = z.infer<typeof AutoTunePhaseResultSchema>;
|
|
875
|
+
export type AutoTuneWarning = z.infer<typeof AutoTuneWarningSchema>;
|
|
850
876
|
export type DetectorStoreClear = z.infer<typeof DetectorStoreClearSchema>;
|
|
851
|
-
export type
|
|
852
|
-
export type
|
|
877
|
+
export type AutoTuneCameraOverrideClear = z.infer<typeof CameraOverrideClearSchema>;
|
|
878
|
+
export type AutoTuneNodeDeviceChange = z.infer<typeof NodeDeviceChangeSchema>;
|
|
853
879
|
export type HardwareClassId = z.infer<typeof HardwareClassIdSchema>;
|
|
854
880
|
export type AcceleratorKind = z.infer<typeof AcceleratorKindSchema>;
|
|
855
881
|
export type RecommendationReason = z.infer<typeof RecommendationReasonSchema>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
2
|
+
* The Auto tune recommender (D745): one detector per node, from ONE family
|
|
3
3
|
* (YOLOv9) for the whole cluster, chosen from static hardware facts × the
|
|
4
4
|
* measured latency table × the node's detection demand. Pure; no benchmark.
|
|
5
5
|
*
|
|
@@ -24,30 +24,30 @@ import type { ModelFormat } from '../../types/models.js';
|
|
|
24
24
|
import { type DetectorPerfTable } from './detector-performance.js';
|
|
25
25
|
import type { DeviceDemand, NodeRecommendation } from './plan-schemas.js';
|
|
26
26
|
/** The family the cluster runs. */
|
|
27
|
-
export declare const
|
|
27
|
+
export declare const AUTO_TUNE_FAMILY = "yolov9";
|
|
28
28
|
/** Recall within this of the best counts as a tie — the faster one wins. */
|
|
29
29
|
export declare const RECALL_TIE = 0.02;
|
|
30
30
|
/** Default share of an accelerator's throughput kept free. */
|
|
31
31
|
export declare const DEFAULT_HEADROOM = 0.4;
|
|
32
32
|
/** One device of a node, as the recommender reads it. */
|
|
33
|
-
export interface
|
|
33
|
+
export interface AutoTuneDeviceInput {
|
|
34
34
|
readonly key: string;
|
|
35
35
|
readonly format: ModelFormat;
|
|
36
36
|
readonly enabled: boolean;
|
|
37
37
|
readonly available: boolean;
|
|
38
38
|
}
|
|
39
39
|
/** One node, as the recommender reads it. */
|
|
40
|
-
export interface
|
|
40
|
+
export interface AutoTuneNodeInput {
|
|
41
41
|
readonly nodeId: string;
|
|
42
42
|
readonly reachable: boolean;
|
|
43
43
|
readonly hardware: HardwareInfo | null;
|
|
44
|
-
readonly devices: readonly
|
|
44
|
+
readonly devices: readonly AutoTuneDeviceInput[];
|
|
45
45
|
/** Object-detection model id → the formats it has a build for, from the node's catalog. */
|
|
46
46
|
readonly formatsByModel: Readonly<Record<string, readonly ModelFormat[]>>;
|
|
47
47
|
}
|
|
48
48
|
/** Recommend one node. See the module header. */
|
|
49
49
|
export declare function recommendNode(input: {
|
|
50
|
-
readonly node:
|
|
50
|
+
readonly node: AutoTuneNodeInput;
|
|
51
51
|
readonly demand: readonly DeviceDemand[];
|
|
52
52
|
readonly headroom?: number;
|
|
53
53
|
readonly perf?: DetectorPerfTable;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shares a session election actually reads, and the view the Load
|
|
3
|
+
* balancing tab shows (D750). Pure.
|
|
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
|
|
7
|
+
* node or device that cannot take a session now (offline, switched off, no
|
|
8
|
+
* detect capability, unable to run the root) contributes nothing, and the
|
|
9
|
+
* others split its share in proportion to their own. That redistribution is
|
|
10
|
+
* exactly what `electByShare` does over its candidate set, so the view and
|
|
11
|
+
* the election cannot disagree; the stored values are never rewritten for it.
|
|
12
|
+
*/
|
|
13
|
+
import type { EffectiveShares, SessionPlacementPolicy, ShareSource, ShareWeights } from './schemas.js';
|
|
14
|
+
export interface EffectiveSharesInput {
|
|
15
|
+
readonly source: ShareSource;
|
|
16
|
+
/** Every node the view covers, eligible or not. */
|
|
17
|
+
readonly nodeIds: readonly string[];
|
|
18
|
+
readonly stored: ShareWeights;
|
|
19
|
+
/** The last automatic computation; null = none yet. */
|
|
20
|
+
readonly auto: ShareWeights | null;
|
|
21
|
+
readonly eligibleNodes: readonly string[];
|
|
22
|
+
/** nodeId → device keys that can take sessions; a node absent here lists none. */
|
|
23
|
+
readonly eligibleDevices: Readonly<Record<string, readonly string[]>>;
|
|
24
|
+
readonly policy?: SessionPlacementPolicy;
|
|
25
|
+
readonly computedAt?: number | null;
|
|
26
|
+
readonly trigger?: string | null;
|
|
27
|
+
}
|
|
28
|
+
export declare function resolveEffectiveShares(input: EffectiveSharesInput): EffectiveShares;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Load balancing (D748, D750): the share placement policy for detection
|
|
3
|
+
* sessions, where its shares come from, and the shapes of its admin surface.
|
|
4
|
+
* See `share-election.ts` and `effective-shares.ts`.
|
|
5
|
+
*/
|
|
6
|
+
export * from './share-election.js';
|
|
7
|
+
export * from './schemas.js';
|
|
8
|
+
export * from './effective-shares.js';
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire shapes of the Load balancing surface (D748): the session placement
|
|
3
|
+
* policy, the atomic share write, the observed placement statistics, the
|
|
4
|
+
* hardware share suggestion and the stale device pins.
|
|
5
|
+
*/
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
/**
|
|
8
|
+
* How a new detection session picks its node and device.
|
|
9
|
+
* - `least-loaded` — the historical rule: lowest `attached / weight`, a
|
|
10
|
+
* constant node order at a tie (D37). An idle node always ties at 0, so a
|
|
11
|
+
* weight only bites once a node already holds a session.
|
|
12
|
+
* - `share` — the share of PARALLEL sessions is held to the weights, and a
|
|
13
|
+
* full or drowning node yields to a free one (D748).
|
|
14
|
+
*/
|
|
15
|
+
export declare const SessionPlacementPolicySchema: z.ZodEnum<{
|
|
16
|
+
"least-loaded": "least-loaded";
|
|
17
|
+
share: "share";
|
|
18
|
+
}>;
|
|
19
|
+
export type SessionPlacementPolicy = z.infer<typeof SessionPlacementPolicySchema>;
|
|
20
|
+
/**
|
|
21
|
+
* `share` since D750: the percentages are held by default. `least-loaded` stays
|
|
22
|
+
* selectable.
|
|
23
|
+
*/
|
|
24
|
+
export declare const DEFAULT_SESSION_PLACEMENT_POLICY: SessionPlacementPolicy;
|
|
25
|
+
/** The global-settings key the policy is stored under (orchestrator `load` section). */
|
|
26
|
+
export declare const SESSION_PLACEMENT_SETTING_KEY = "sessionPlacement";
|
|
27
|
+
/** Parse a stored value; anything unknown is the default. */
|
|
28
|
+
export declare function parseSessionPlacementPolicy(value: unknown): SessionPlacementPolicy;
|
|
29
|
+
export declare const LoadBalancingSharesInputSchema: z.ZodObject<{
|
|
30
|
+
nodes: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
31
|
+
devices: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodNumber>>>;
|
|
32
|
+
}, z.core.$strip>;
|
|
33
|
+
export type LoadBalancingSharesInput = z.infer<typeof LoadBalancingSharesInputSchema>;
|
|
34
|
+
export declare const PlacementStatsInputSchema: z.ZodObject<{
|
|
35
|
+
windowMs: z.ZodDefault<z.ZodNumber>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
export type PlacementStatsInput = z.infer<typeof PlacementStatsInputSchema>;
|
|
38
|
+
export declare const PlacementDeviceStatsSchema: z.ZodObject<{
|
|
39
|
+
deviceKey: z.ZodString;
|
|
40
|
+
sessionsNow: z.ZodNumber;
|
|
41
|
+
sessionsStarted: z.ZodNumber;
|
|
42
|
+
observedShare: z.ZodNullable<z.ZodNumber>;
|
|
43
|
+
}, z.core.$strip>;
|
|
44
|
+
export type PlacementDeviceStats = z.infer<typeof PlacementDeviceStatsSchema>;
|
|
45
|
+
export declare const PlacementNodeStatsSchema: z.ZodObject<{
|
|
46
|
+
nodeId: z.ZodString;
|
|
47
|
+
sessionsNow: z.ZodNumber;
|
|
48
|
+
sessionsStarted: z.ZodNumber;
|
|
49
|
+
observedShare: z.ZodNullable<z.ZodNumber>;
|
|
50
|
+
peakSessions: z.ZodNumber;
|
|
51
|
+
yieldsAway: z.ZodNumber;
|
|
52
|
+
devices: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
53
|
+
deviceKey: z.ZodString;
|
|
54
|
+
sessionsNow: z.ZodNumber;
|
|
55
|
+
sessionsStarted: z.ZodNumber;
|
|
56
|
+
observedShare: z.ZodNullable<z.ZodNumber>;
|
|
57
|
+
}, z.core.$strip>>>;
|
|
58
|
+
}, z.core.$strip>;
|
|
59
|
+
export type PlacementNodeStats = z.infer<typeof PlacementNodeStatsSchema>;
|
|
60
|
+
/** A camera's device pin that the session path cannot honour. */
|
|
61
|
+
export declare const StaleDevicePinSchema: z.ZodObject<{
|
|
62
|
+
deviceId: z.ZodNumber;
|
|
63
|
+
deviceKey: z.ZodString;
|
|
64
|
+
reason: z.ZodEnum<{
|
|
65
|
+
absent: "absent";
|
|
66
|
+
disabled: "disabled";
|
|
67
|
+
}>;
|
|
68
|
+
}, z.core.$strip>;
|
|
69
|
+
export type StaleDevicePin = z.infer<typeof StaleDevicePinSchema>;
|
|
70
|
+
export declare const PlacementStatsSchema: z.ZodObject<{
|
|
71
|
+
policy: z.ZodEnum<{
|
|
72
|
+
"least-loaded": "least-loaded";
|
|
73
|
+
share: "share";
|
|
74
|
+
}>;
|
|
75
|
+
windowMs: z.ZodNumber;
|
|
76
|
+
observedForMs: z.ZodNumber;
|
|
77
|
+
sessionsNow: z.ZodNumber;
|
|
78
|
+
clusterPeakSessions: z.ZodNumber;
|
|
79
|
+
nodes: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
80
|
+
nodeId: z.ZodString;
|
|
81
|
+
sessionsNow: z.ZodNumber;
|
|
82
|
+
sessionsStarted: z.ZodNumber;
|
|
83
|
+
observedShare: z.ZodNullable<z.ZodNumber>;
|
|
84
|
+
peakSessions: z.ZodNumber;
|
|
85
|
+
yieldsAway: z.ZodNumber;
|
|
86
|
+
devices: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
87
|
+
deviceKey: z.ZodString;
|
|
88
|
+
sessionsNow: z.ZodNumber;
|
|
89
|
+
sessionsStarted: z.ZodNumber;
|
|
90
|
+
observedShare: z.ZodNullable<z.ZodNumber>;
|
|
91
|
+
}, z.core.$strip>>>;
|
|
92
|
+
}, z.core.$strip>>>;
|
|
93
|
+
stalePins: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
94
|
+
deviceId: z.ZodNumber;
|
|
95
|
+
deviceKey: z.ZodString;
|
|
96
|
+
reason: z.ZodEnum<{
|
|
97
|
+
absent: "absent";
|
|
98
|
+
disabled: "disabled";
|
|
99
|
+
}>;
|
|
100
|
+
}, z.core.$strip>>>;
|
|
101
|
+
}, z.core.$strip>;
|
|
102
|
+
export type PlacementStats = z.infer<typeof PlacementStatsSchema>;
|
|
103
|
+
export declare const SuggestSharesInputSchema: z.ZodObject<{
|
|
104
|
+
headroom: z.ZodDefault<z.ZodNumber>;
|
|
105
|
+
}, z.core.$strip>;
|
|
106
|
+
export type SuggestSharesInput = z.infer<typeof SuggestSharesInputSchema>;
|
|
107
|
+
export declare const SuggestedDeviceShareSchema: z.ZodObject<{
|
|
108
|
+
deviceKey: z.ZodString;
|
|
109
|
+
share: z.ZodNumber;
|
|
110
|
+
modelId: z.ZodNullable<z.ZodString>;
|
|
111
|
+
fps: z.ZodNullable<z.ZodNumber>;
|
|
112
|
+
measured: z.ZodBoolean;
|
|
113
|
+
suggestedMaxSessions: z.ZodNullable<z.ZodNumber>;
|
|
114
|
+
}, z.core.$strip>;
|
|
115
|
+
export type SuggestedDeviceShare = z.infer<typeof SuggestedDeviceShareSchema>;
|
|
116
|
+
export declare const SuggestedNodeShareSchema: z.ZodObject<{
|
|
117
|
+
nodeId: z.ZodString;
|
|
118
|
+
share: z.ZodNullable<z.ZodNumber>;
|
|
119
|
+
capacitySessions: z.ZodNumber;
|
|
120
|
+
devices: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
121
|
+
deviceKey: z.ZodString;
|
|
122
|
+
share: z.ZodNumber;
|
|
123
|
+
modelId: z.ZodNullable<z.ZodString>;
|
|
124
|
+
fps: z.ZodNullable<z.ZodNumber>;
|
|
125
|
+
measured: z.ZodBoolean;
|
|
126
|
+
suggestedMaxSessions: z.ZodNullable<z.ZodNumber>;
|
|
127
|
+
}, z.core.$strip>>>;
|
|
128
|
+
skippedReason: z.ZodNullable<z.ZodString>;
|
|
129
|
+
}, z.core.$strip>;
|
|
130
|
+
export type SuggestedNodeShare = z.infer<typeof SuggestedNodeShareSchema>;
|
|
131
|
+
export declare const SuggestSharesResultSchema: z.ZodObject<{
|
|
132
|
+
headroom: z.ZodNumber;
|
|
133
|
+
cameraFps: z.ZodNumber;
|
|
134
|
+
iterations: z.ZodNumber;
|
|
135
|
+
nodes: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
136
|
+
nodeId: z.ZodString;
|
|
137
|
+
share: z.ZodNullable<z.ZodNumber>;
|
|
138
|
+
capacitySessions: z.ZodNumber;
|
|
139
|
+
devices: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
140
|
+
deviceKey: z.ZodString;
|
|
141
|
+
share: z.ZodNumber;
|
|
142
|
+
modelId: z.ZodNullable<z.ZodString>;
|
|
143
|
+
fps: z.ZodNullable<z.ZodNumber>;
|
|
144
|
+
measured: z.ZodBoolean;
|
|
145
|
+
suggestedMaxSessions: z.ZodNullable<z.ZodNumber>;
|
|
146
|
+
}, z.core.$strip>>>;
|
|
147
|
+
skippedReason: z.ZodNullable<z.ZodString>;
|
|
148
|
+
}, z.core.$strip>>>;
|
|
149
|
+
}, z.core.$strip>;
|
|
150
|
+
export type SuggestSharesResult = z.infer<typeof SuggestSharesResultSchema>;
|
|
151
|
+
/**
|
|
152
|
+
* Where the node and device shares come from (D750).
|
|
153
|
+
* - `auto` — computed by the system from the cluster's measured capacity at
|
|
154
|
+
* the Auto tune models, and recomputed whenever a node or device joins,
|
|
155
|
+
* leaves, is switched on or off, or changes model.
|
|
156
|
+
* - `manual` — the operator's stored sliders. A node or device that cannot
|
|
157
|
+
* take sessions gives its share to the others in proportion; the stored
|
|
158
|
+
* values are never rewritten for that.
|
|
159
|
+
*/
|
|
160
|
+
export declare const ShareSourceSchema: z.ZodEnum<{
|
|
161
|
+
manual: "manual";
|
|
162
|
+
auto: "auto";
|
|
163
|
+
}>;
|
|
164
|
+
export type ShareSource = z.infer<typeof ShareSourceSchema>;
|
|
165
|
+
export declare const DEFAULT_SHARE_SOURCE: ShareSource;
|
|
166
|
+
/** Headroom the automatic shares are computed at (Auto tune's default). */
|
|
167
|
+
export declare const AUTO_SHARE_HEADROOM = 0.4;
|
|
168
|
+
/** The global-settings key the share source is stored under (orchestrator `load` section). */
|
|
169
|
+
export declare const SHARE_SOURCE_SETTING_KEY = "shareSource";
|
|
170
|
+
/** Parse a stored value; anything unknown is the default. */
|
|
171
|
+
export declare function parseShareSource(value: unknown): ShareSource;
|
|
172
|
+
export declare const SetShareSourceInputSchema: z.ZodObject<{
|
|
173
|
+
source: z.ZodEnum<{
|
|
174
|
+
manual: "manual";
|
|
175
|
+
auto: "auto";
|
|
176
|
+
}>;
|
|
177
|
+
}, z.core.$strip>;
|
|
178
|
+
export type SetShareSourceInput = z.infer<typeof SetShareSourceInputSchema>;
|
|
179
|
+
/** Raw relative weights (any scale) per node and per node's device. */
|
|
180
|
+
export declare const ShareWeightsSchema: z.ZodObject<{
|
|
181
|
+
nodes: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
182
|
+
devices: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
183
|
+
}, z.core.$strip>;
|
|
184
|
+
export type ShareWeights = z.infer<typeof ShareWeightsSchema>;
|
|
185
|
+
export declare const EffectiveDeviceShareSchema: z.ZodObject<{
|
|
186
|
+
deviceKey: z.ZodString;
|
|
187
|
+
eligible: z.ZodBoolean;
|
|
188
|
+
configuredPct: z.ZodNumber;
|
|
189
|
+
effectivePct: z.ZodNumber;
|
|
190
|
+
}, z.core.$strip>;
|
|
191
|
+
export type EffectiveDeviceShare = z.infer<typeof EffectiveDeviceShareSchema>;
|
|
192
|
+
export declare const EffectiveNodeShareSchema: z.ZodObject<{
|
|
193
|
+
nodeId: z.ZodString;
|
|
194
|
+
eligible: z.ZodBoolean;
|
|
195
|
+
configuredPct: z.ZodNumber;
|
|
196
|
+
effectivePct: z.ZodNumber;
|
|
197
|
+
devices: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
198
|
+
deviceKey: z.ZodString;
|
|
199
|
+
eligible: z.ZodBoolean;
|
|
200
|
+
configuredPct: z.ZodNumber;
|
|
201
|
+
effectivePct: z.ZodNumber;
|
|
202
|
+
}, z.core.$strip>>>;
|
|
203
|
+
}, z.core.$strip>;
|
|
204
|
+
export type EffectiveNodeShare = z.infer<typeof EffectiveNodeShareSchema>;
|
|
205
|
+
export declare const EffectiveSharesSchema: z.ZodObject<{
|
|
206
|
+
source: z.ZodEnum<{
|
|
207
|
+
manual: "manual";
|
|
208
|
+
auto: "auto";
|
|
209
|
+
}>;
|
|
210
|
+
policy: z.ZodEnum<{
|
|
211
|
+
"least-loaded": "least-loaded";
|
|
212
|
+
share: "share";
|
|
213
|
+
}>;
|
|
214
|
+
autoPending: z.ZodBoolean;
|
|
215
|
+
computedAt: z.ZodNullable<z.ZodNumber>;
|
|
216
|
+
trigger: z.ZodNullable<z.ZodString>;
|
|
217
|
+
nodes: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
218
|
+
nodeId: z.ZodString;
|
|
219
|
+
eligible: z.ZodBoolean;
|
|
220
|
+
configuredPct: z.ZodNumber;
|
|
221
|
+
effectivePct: z.ZodNumber;
|
|
222
|
+
devices: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
223
|
+
deviceKey: z.ZodString;
|
|
224
|
+
eligible: z.ZodBoolean;
|
|
225
|
+
configuredPct: z.ZodNumber;
|
|
226
|
+
effectivePct: z.ZodNumber;
|
|
227
|
+
}, z.core.$strip>>>;
|
|
228
|
+
}, z.core.$strip>>>;
|
|
229
|
+
nodeWeights: z.ZodRecord<z.ZodString, z.ZodNumber>;
|
|
230
|
+
deviceWeights: z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
231
|
+
}, z.core.$strip>;
|
|
232
|
+
export type EffectiveShares = z.infer<typeof EffectiveSharesSchema>;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Share placement (D748): which node — or which device of a node — a NEW
|
|
3
|
+
* detection session goes to when the cluster's `sessionPlacement` policy is
|
|
4
|
+
* `share`. Pure.
|
|
5
|
+
*
|
|
6
|
+
* A share is a share of PARALLEL sessions. At each session start the
|
|
7
|
+
* candidate furthest below its share of the sessions running once this one
|
|
8
|
+
* starts wins:
|
|
9
|
+
*
|
|
10
|
+
* deficit_i = share_i / Σshare × (Σrunning + 1) − running_i
|
|
11
|
+
*
|
|
12
|
+
* so with 70/20/10 and an empty cluster the first session goes to the 70,
|
|
13
|
+
* and ten concurrent sessions settle at 7/2/1. Sessions a pin placed count
|
|
14
|
+
* toward their candidate like any other — a pinned node is not owed extra.
|
|
15
|
+
*
|
|
16
|
+
* Work-conserving: when the turn holder has no room — at an EXPLICIT cap
|
|
17
|
+
* (`maxSessions` / `maxCameras`) or drowning (its pool at the shed cap) — the
|
|
18
|
+
* session goes to the free candidate with the most spare explicit capacity,
|
|
19
|
+
* then the largest deficit. Never onto a saturated one. A capacity derived
|
|
20
|
+
* from the measured latency table is advisory only and never enters here: it
|
|
21
|
+
* would turn a suggestion into a de-facto cap.
|
|
22
|
+
*
|
|
23
|
+
* When every uncapped candidate is saturated the turn holder keeps the
|
|
24
|
+
* session: excluding the whole set would silently disable placement.
|
|
25
|
+
*/
|
|
26
|
+
export interface ShareCandidate {
|
|
27
|
+
readonly key: string;
|
|
28
|
+
/** Relative share (any scale; ≤ 0 = wanted last). */
|
|
29
|
+
readonly share: number;
|
|
30
|
+
/** Sessions running on this candidate now. */
|
|
31
|
+
readonly running: number;
|
|
32
|
+
/** At an explicit cap — never elected. */
|
|
33
|
+
readonly capped: boolean;
|
|
34
|
+
/** Drowning (pool queue at its shed cap) — stepped over while another is free. */
|
|
35
|
+
readonly saturated: boolean;
|
|
36
|
+
/** Spare sessions under an explicit cap; absent = no explicit cap. */
|
|
37
|
+
readonly spare?: number;
|
|
38
|
+
}
|
|
39
|
+
export type ShareYieldReason = 'at-cap' | 'saturated';
|
|
40
|
+
export type ShareElection = {
|
|
41
|
+
readonly kind: 'elected';
|
|
42
|
+
readonly key: string;
|
|
43
|
+
readonly reason: 'share';
|
|
44
|
+
} | {
|
|
45
|
+
readonly kind: 'elected';
|
|
46
|
+
readonly key: string;
|
|
47
|
+
readonly reason: 'yield';
|
|
48
|
+
/** The candidate whose turn it was. */
|
|
49
|
+
readonly turnKey: string;
|
|
50
|
+
readonly yieldReason: ShareYieldReason;
|
|
51
|
+
} | {
|
|
52
|
+
readonly kind: 'none';
|
|
53
|
+
};
|
|
54
|
+
export declare function electByShare(candidates: readonly ShareCandidate[]): ShareElection;
|
|
@@ -84,6 +84,6 @@ export declare function clearModelBoundOverrides(settings: ModelBoundSettingsBag
|
|
|
84
84
|
/**
|
|
85
85
|
* The keys of every `bindsToModel` field of a step's config schema, groups
|
|
86
86
|
* flattened (D738). One definition for the runner (which applies the binding)
|
|
87
|
-
* and the orchestrator's
|
|
87
|
+
* and the orchestrator's Auto tune (which clears those overrides, D745).
|
|
88
88
|
*/
|
|
89
89
|
export declare function collectModelBoundKeys(fields: readonly ConfigField[]): string[];
|
|
@@ -157,7 +157,6 @@ export interface AgentPipelineSettings {
|
|
|
157
157
|
* resolved tree.
|
|
158
158
|
*/
|
|
159
159
|
export interface CameraPipelineSettings {
|
|
160
|
-
readonly pinnedAgentNodeId?: string;
|
|
161
160
|
readonly stepToggles?: Readonly<Record<string, boolean>>;
|
|
162
161
|
/**
|
|
163
162
|
* Per-(camera,node,device) model/settings override. Addressed by
|
package/package.json
CHANGED
|
File without changes
|