@camstack/addon-pipeline-orchestrator 1.2.295 → 1.2.296
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/_stub.js +51 -51
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-AWzVk6zp.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-ClO9DjMF.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BAA5Kwgx.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BGNuYCGq.mjs +26 -0
- package/dist/{hostInit-B1qObv0b.mjs → hostInit-cCd7B0HK.mjs} +3 -3
- package/dist/index.js +127 -368
- package/dist/index.mjs +127 -368
- package/dist/remoteEntry.js +1 -1
- package/package.json +1 -1
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-Coy6cr5o.mjs +0 -26
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-DBOk63Cu.mjs +0 -26
package/dist/index.mjs
CHANGED
|
@@ -2,7 +2,7 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
//#region ../types/dist/event-category-
|
|
5
|
+
//#region ../types/dist/event-category-B_0XEcLF.mjs
|
|
6
6
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
7
7
|
EventCategory["SystemBoot"] = "system.boot";
|
|
8
8
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -503,15 +503,6 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
503
503
|
EventCategory["AgentWsDisconnected"] = "agent.ws.disconnected";
|
|
504
504
|
EventCategory["AgentBackupActivated"] = "agent.backup.activated";
|
|
505
505
|
EventCategory["OrchestrationSettingsUpdated"] = "orchestration.settings-updated";
|
|
506
|
-
/**
|
|
507
|
-
* Per-agent hwaccel preference changed (user override set, cleared, or
|
|
508
|
-
* re-probed). Observability event — decoders pull the current pref at
|
|
509
|
-
* `createSession`, so running sessions keep their current backend until
|
|
510
|
-
* they rotate naturally (camera add/remove, stream restart). Future
|
|
511
|
-
* work can wire a listener in stream-broker that force-rotates live
|
|
512
|
-
* sessions; for now this event powers logs + admin-UI toast feedback.
|
|
513
|
-
*/
|
|
514
|
-
EventCategory["PipelineAgentHwaccelChanged"] = "pipeline.agent-hwaccel-changed";
|
|
515
506
|
EventCategory["MotionAnalysis"] = "detection.motion-analysis";
|
|
516
507
|
/** All raw motion zones from CCL before minArea filter — for UI debug overlay. */
|
|
517
508
|
EventCategory["MotionZonesRaw"] = "detection.motion-zones-raw";
|
|
@@ -5382,7 +5373,7 @@ var ZodIssueCode = {
|
|
|
5382
5373
|
var ZodFirstPartyTypeKind;
|
|
5383
5374
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5384
5375
|
//#endregion
|
|
5385
|
-
//#region ../types/dist/sleep-
|
|
5376
|
+
//#region ../types/dist/sleep-BNeXenvr.mjs
|
|
5386
5377
|
/**
|
|
5387
5378
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5388
5379
|
* window to float samples (D455).
|
|
@@ -6781,32 +6772,12 @@ object({
|
|
|
6781
6772
|
audioCodec: string().optional(),
|
|
6782
6773
|
metadata: record(string(), unknown()).readonly().optional()
|
|
6783
6774
|
});
|
|
6784
|
-
var EncodedPacketSchema = object({
|
|
6785
|
-
type: _enum(["video", "audio"]),
|
|
6786
|
-
data: _instanceof(Uint8Array),
|
|
6787
|
-
pts: number(),
|
|
6788
|
-
dts: number(),
|
|
6789
|
-
keyframe: boolean(),
|
|
6790
|
-
codec: string()
|
|
6791
|
-
});
|
|
6792
|
-
var DecodedFrameSchema = object({
|
|
6793
|
-
data: _instanceof(Uint8Array),
|
|
6794
|
-
width: number(),
|
|
6795
|
-
height: number(),
|
|
6796
|
-
format: _enum([
|
|
6797
|
-
"jpeg",
|
|
6798
|
-
"rgb",
|
|
6799
|
-
"bgr",
|
|
6800
|
-
"yuv420",
|
|
6801
|
-
"gray"
|
|
6802
|
-
]),
|
|
6803
|
-
timestamp: number()
|
|
6804
|
-
});
|
|
6805
6775
|
/**
|
|
6806
6776
|
* Wire schema for `FrameHandle` — a zero-pixel, serialisable reference to a
|
|
6807
6777
|
* frame in a shared-memory ring (Phase 5 / D9). Mirrors the `FrameHandle` TS
|
|
6808
|
-
* interface in `interfaces/frame-handle.ts` field-for-field so a
|
|
6809
|
-
*
|
|
6778
|
+
* interface in `interfaces/frame-handle.ts` field-for-field so a cap method
|
|
6779
|
+
* (the runner's native-crop and pipeline-executor inputs) can carry handles
|
|
6780
|
+
* over tRPC / Moleculer.
|
|
6810
6781
|
*
|
|
6811
6782
|
* The `satisfies` assertion below pins this schema to the interface: if a
|
|
6812
6783
|
* field is added to / removed from `FrameHandle` without a matching schema
|
|
@@ -6832,50 +6803,6 @@ var FrameHandleSchema = object({
|
|
|
6832
6803
|
slotCount: number().int().positive()
|
|
6833
6804
|
});
|
|
6834
6805
|
/**
|
|
6835
|
-
* Pixel format a frame-handle subscriber can request from the broker
|
|
6836
|
-
* (Phase 5 / D9). The packed, raster subset of `FrameFormat` — the formats a
|
|
6837
|
-
* `frameSink: 'shm'` decoder session can write into a `FrameRing` slot.
|
|
6838
|
-
* `jpeg` is excluded: a variable-length stream is not a fixed-stride ring
|
|
6839
|
-
* payload, and no decoded-frame consumer requests it over the shm plane.
|
|
6840
|
-
*/
|
|
6841
|
-
var FrameHandleFormatSchema = _enum([
|
|
6842
|
-
"rgb",
|
|
6843
|
-
"bgr",
|
|
6844
|
-
"yuv420",
|
|
6845
|
-
"gray"
|
|
6846
|
-
]);
|
|
6847
|
-
/**
|
|
6848
|
-
* Input for `stream-broker.subscribeFrames` (Phase 5 / D9). A consumer asks the
|
|
6849
|
-
* broker for a `FrameHandle` stream of one `format`; the broker maintains one
|
|
6850
|
-
* shared-memory ring per `(brokerId, format)` actually requested, so a `gray`
|
|
6851
|
-
* subscriber (motion) and an `rgb` subscriber (detection) each read the format
|
|
6852
|
-
* they asked for with no broker-side conversion.
|
|
6853
|
-
*/
|
|
6854
|
-
var SubscribeFramesInputSchema = object({
|
|
6855
|
-
brokerId: string(),
|
|
6856
|
-
format: FrameHandleFormatSchema,
|
|
6857
|
-
/**
|
|
6858
|
-
* Optional reader-side cadence hint in frames per second. The broker does
|
|
6859
|
-
* NOT throttle — latest-wins ring reads drop frames implicitly for a slow
|
|
6860
|
-
* consumer. The value is echoed back in `SubscribeFramesResult.maxFps` so
|
|
6861
|
-
* the consumer can pace its own `pullFrameHandles` polling.
|
|
6862
|
-
*/
|
|
6863
|
-
maxFps: number().positive().optional(),
|
|
6864
|
-
/** Short caller-identity tag (`motion`, `detection`, …) for diagnostics. */
|
|
6865
|
-
tag: string().optional()
|
|
6866
|
-
});
|
|
6867
|
-
/**
|
|
6868
|
-
* Result of `stream-broker.subscribeFrames`. The consumer then polls
|
|
6869
|
-
* `pullFrameHandles({ subscriptionId, maxCount })` and feeds each returned
|
|
6870
|
-
* `FrameHandle` to a `FrameRingReader`.
|
|
6871
|
-
*/
|
|
6872
|
-
var SubscribeFramesResultSchema = object({
|
|
6873
|
-
/** Opaque id the consumer passes to `pullFrameHandles` / `unsubscribeFrames`. */
|
|
6874
|
-
subscriptionId: string(),
|
|
6875
|
-
/** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
|
|
6876
|
-
maxFps: number().nonnegative()
|
|
6877
|
-
});
|
|
6878
|
-
/**
|
|
6879
6806
|
* Wire schema for a decoded audio chunk (Phase 5 / D9). Mirrors the
|
|
6880
6807
|
* `DecodedAudioChunk` TS interface in `interfaces/stream-broker.ts`: PCM
|
|
6881
6808
|
* sample bytes plus the track parameters a consumer needs to interpret them.
|
|
@@ -6883,8 +6810,8 @@ var SubscribeFramesResultSchema = object({
|
|
|
6883
6810
|
* Audio chunks are tiny (a ~500ms AudioCodecSession window is a few KB of
|
|
6884
6811
|
* Float32 PCM), so unlike video frames they ship their bytes INLINE over
|
|
6885
6812
|
* tRPC / Moleculer — no shared-memory plane. `data` is typed `Uint8Array`
|
|
6886
|
-
* (the wire-serialisable supertype of `Buffer`)
|
|
6887
|
-
*
|
|
6813
|
+
* (the wire-serialisable supertype of `Buffer`); a `Buffer` is assignable to
|
|
6814
|
+
* it.
|
|
6888
6815
|
*/
|
|
6889
6816
|
var AudioChunkFormatSchema = _enum(AUDIO_CHUNK_FORMATS);
|
|
6890
6817
|
var DecodedAudioChunkSchema = object({
|
|
@@ -6902,11 +6829,10 @@ var DecodedAudioChunkSchema = object({
|
|
|
6902
6829
|
format: AudioChunkFormatSchema.optional()
|
|
6903
6830
|
});
|
|
6904
6831
|
/**
|
|
6905
|
-
* Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9).
|
|
6906
|
-
*
|
|
6907
|
-
*
|
|
6908
|
-
*
|
|
6909
|
-
* `pullAudioChunks`.
|
|
6832
|
+
* Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9). Audio ships
|
|
6833
|
+
* its bytes inline: a consumer asks the broker for the decoded audio-chunk
|
|
6834
|
+
* stream of one broker; the broker keeps a per-subscription bounded FIFO queue
|
|
6835
|
+
* the consumer drains via `pullAudioChunks`.
|
|
6910
6836
|
*/
|
|
6911
6837
|
var SubscribeAudioChunksInputSchema = object({
|
|
6912
6838
|
brokerId: string(),
|
|
@@ -6937,9 +6863,7 @@ var BrokerStatsSchema = object({
|
|
|
6937
6863
|
"stopped"
|
|
6938
6864
|
]),
|
|
6939
6865
|
inputFps: number(),
|
|
6940
|
-
decodeFps: number(),
|
|
6941
6866
|
encodedSubscribers: number(),
|
|
6942
|
-
decodedSubscribers: number(),
|
|
6943
6867
|
uptimeMs: number(),
|
|
6944
6868
|
bitrateKbps: number(),
|
|
6945
6869
|
idrIntervalMs: number(),
|
|
@@ -6952,14 +6876,6 @@ var BrokerStatsSchema = object({
|
|
|
6952
6876
|
preBufferMs: number(),
|
|
6953
6877
|
preBufferPackets: number(),
|
|
6954
6878
|
/**
|
|
6955
|
-
* Moleculer node id of the decoder provider currently servicing this
|
|
6956
|
-
* stream's decoded subscribers. `null` until the deferred decoder is
|
|
6957
|
-
* created (no decoded clients yet, or codec not detected). Surfaces the
|
|
6958
|
-
* runtime decoder placement so the UI can show "Decoder: <agent>" without
|
|
6959
|
-
* a separate cap call per broker.
|
|
6960
|
-
*/
|
|
6961
|
-
decoderNodeId: string().nullable(),
|
|
6962
|
-
/**
|
|
6963
6879
|
* Detected audio track parameters from the RTSP DESCRIBE / SDP. `null`
|
|
6964
6880
|
* when the stream has no audio track or the broker is in cold start.
|
|
6965
6881
|
* `supported = false` means the codec was detected but the local
|
|
@@ -11297,70 +11213,6 @@ var StorageLocationDeclarationSchema = object({
|
|
|
11297
11213
|
"backup"
|
|
11298
11214
|
]).optional()
|
|
11299
11215
|
});
|
|
11300
|
-
var DecoderStatsSchema = object({
|
|
11301
|
-
inputFps: number(),
|
|
11302
|
-
outputFps: number(),
|
|
11303
|
-
avgDecodeTimeMs: number(),
|
|
11304
|
-
droppedFrames: number(),
|
|
11305
|
-
/**
|
|
11306
|
-
* Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
|
|
11307
|
-
* lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
|
|
11308
|
-
* the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
|
|
11309
|
-
* is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
|
|
11310
|
-
*/
|
|
11311
|
-
lagMs: number().optional(),
|
|
11312
|
-
effectiveFps: number().optional(),
|
|
11313
|
-
adaptiveFps: number().optional()
|
|
11314
|
-
});
|
|
11315
|
-
var DecoderSessionConfigSchema = object({
|
|
11316
|
-
codec: string(),
|
|
11317
|
-
maxFps: number().default(0),
|
|
11318
|
-
outputFormat: _enum([
|
|
11319
|
-
"jpeg",
|
|
11320
|
-
"rgb",
|
|
11321
|
-
"bgr",
|
|
11322
|
-
"yuv420",
|
|
11323
|
-
"gray"
|
|
11324
|
-
]).default("jpeg"),
|
|
11325
|
-
scale: number().default(1),
|
|
11326
|
-
width: number().optional(),
|
|
11327
|
-
height: number().optional(),
|
|
11328
|
-
/**
|
|
11329
|
-
* Identifier of the camera this decoder session serves. Optional
|
|
11330
|
-
* because the cap is generic (any caller could request decode), but
|
|
11331
|
-
* stream-broker passes it so decoder logs include `deviceId` for
|
|
11332
|
-
* per-camera filtering when diagnosing failures (e.g. node-av
|
|
11333
|
-
* sendPacket errors on a single hung camera).
|
|
11334
|
-
*/
|
|
11335
|
-
deviceId: number().int().nonnegative().optional(),
|
|
11336
|
-
/**
|
|
11337
|
-
* Free-form tag for log scoping. Stream-broker uses
|
|
11338
|
-
* `broker:<deviceId>/<profile>`. Decoder session logger surfaces it
|
|
11339
|
-
* on every line so `grep tag=broker:5/high` filters one camera
|
|
11340
|
-
* profile cleanly.
|
|
11341
|
-
*/
|
|
11342
|
-
tag: string().optional(),
|
|
11343
|
-
/**
|
|
11344
|
-
* Where the session delivers decoded frames (Phase 5 / D9):
|
|
11345
|
-
*
|
|
11346
|
-
* - `'callback'` (default) — the legacy pixel path: decoded frames are
|
|
11347
|
-
* buffered as `DecodedFrame`s and drained via `pullFrames`.
|
|
11348
|
-
* - `'shm'` — the shared-memory frame plane: decoded frames are written
|
|
11349
|
-
* into an OS shared-memory ring and drained as zero-pixel
|
|
11350
|
-
* `FrameHandle`s via `pullHandles`. A session is one mode or the
|
|
11351
|
-
* other — `pullFrames` returns nothing for an `'shm'` session and
|
|
11352
|
-
* `pullHandles` returns nothing for a `'callback'` session.
|
|
11353
|
-
*/
|
|
11354
|
-
frameSink: _enum(["callback", "shm"]).default("callback"),
|
|
11355
|
-
/**
|
|
11356
|
-
* Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
|
|
11357
|
-
* a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
|
|
11358
|
-
* real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
|
|
11359
|
-
* stream-broker's `streamingDebug` gate — off by default so production logs
|
|
11360
|
-
* stay quiet and the emit path pays zero per-frame cost when disabled.
|
|
11361
|
-
*/
|
|
11362
|
-
debug: boolean().optional()
|
|
11363
|
-
});
|
|
11364
11216
|
/**
|
|
11365
11217
|
* Per-component log CHANNELS — the gate a hot path consults, and the registry
|
|
11366
11218
|
* an addon declares its channels in.
|
|
@@ -13564,13 +13416,6 @@ var BrokerRtspClientSchema = object({
|
|
|
13564
13416
|
lastRtpAt: number(),
|
|
13565
13417
|
bytesSent: number()
|
|
13566
13418
|
});
|
|
13567
|
-
var BrokerDecodedClientSchema = object({
|
|
13568
|
-
tag: string(),
|
|
13569
|
-
subscribedAt: number(),
|
|
13570
|
-
maxFps: number(),
|
|
13571
|
-
framesDelivered: number(),
|
|
13572
|
-
framesDropped: number()
|
|
13573
|
-
});
|
|
13574
13419
|
var BrokerAudioClientSchema = object({
|
|
13575
13420
|
tag: string(),
|
|
13576
13421
|
subscribedAt: number(),
|
|
@@ -13662,7 +13507,6 @@ var BrokerEncodedClientSchema = object({
|
|
|
13662
13507
|
});
|
|
13663
13508
|
var BrokerClientsSchema = object({
|
|
13664
13509
|
rtsp: array(BrokerRtspClientSchema).readonly(),
|
|
13665
|
-
decoded: array(BrokerDecodedClientSchema).readonly(),
|
|
13666
13510
|
audio: array(BrokerAudioClientSchema).readonly(),
|
|
13667
13511
|
encoded: array(BrokerEncodedClientSchema).readonly(),
|
|
13668
13512
|
pipeClients: number(),
|
|
@@ -14031,11 +13875,7 @@ method(object({
|
|
|
14031
13875
|
auth: "admin"
|
|
14032
13876
|
}), method(object({ brokerId: string() }), BrokerClientsSchema), method(object({
|
|
14033
13877
|
brokerId: string(),
|
|
14034
|
-
channel: _enum([
|
|
14035
|
-
"rtsp",
|
|
14036
|
-
"decoded",
|
|
14037
|
-
"audio"
|
|
14038
|
-
]),
|
|
13878
|
+
channel: _enum(["rtsp", "audio"]),
|
|
14039
13879
|
handle: string()
|
|
14040
13880
|
}), object({ killed: boolean() }), {
|
|
14041
13881
|
kind: "mutation",
|
|
@@ -14070,10 +13910,7 @@ method(object({
|
|
|
14070
13910
|
}), method(SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, { kind: "mutation" }), method(object({
|
|
14071
13911
|
subscriptionId: string(),
|
|
14072
13912
|
maxCount: number().int().positive().default(8)
|
|
14073
|
-
}), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(
|
|
14074
|
-
subscriptionId: string(),
|
|
14075
|
-
maxCount: number().int().positive().default(4)
|
|
14076
|
-
}), array(FrameHandleSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
|
|
13913
|
+
}), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
|
|
14077
13914
|
brokerId: string(),
|
|
14078
13915
|
seconds: number().min(0).max(30)
|
|
14079
13916
|
}), _void(), {
|
|
@@ -15230,54 +15067,12 @@ id: union([string(), number()]) }), {
|
|
|
15230
15067
|
kind: "mutation",
|
|
15231
15068
|
auth: "admin"
|
|
15232
15069
|
});
|
|
15233
|
-
|
|
15234
|
-
* shm ring usage stats for a `frameSink: 'shm'` decoder session —
|
|
15235
|
-
* exposed via `decoder.getShmStats` so downstream consumers can
|
|
15236
|
-
* observe ring pressure (slot count, byte budget, hit/miss ratio).
|
|
15237
|
-
*/
|
|
15238
|
-
var ShmRingStatsSchema = object({
|
|
15239
|
-
sessionId: string(),
|
|
15240
|
-
slotCount: number().int(),
|
|
15241
|
-
slotByteLength: number().int(),
|
|
15242
|
-
segmentBytes: number().int(),
|
|
15243
|
-
budgetMb: number().int(),
|
|
15244
|
-
framesWritten: number().int(),
|
|
15245
|
-
getFrameHits: number().int(),
|
|
15246
|
-
getFrameMisses: number().int()
|
|
15247
|
-
});
|
|
15248
|
-
method(object({ codec: string() }), boolean()), method(_void(), object({
|
|
15070
|
+
method(_void(), object({
|
|
15249
15071
|
id: string(),
|
|
15250
15072
|
name: string(),
|
|
15251
|
-
isPullMode: boolean().optional(),
|
|
15252
|
-
priority: number().optional(),
|
|
15253
15073
|
hwaccel: string().optional(),
|
|
15254
15074
|
probedBestHwaccel: string().optional()
|
|
15255
|
-
})), method(
|
|
15256
|
-
sessionId: string(),
|
|
15257
|
-
nodeId: string()
|
|
15258
|
-
})), method(object({ sessionId: string() }), _void()), method(object({
|
|
15259
|
-
sessionId: string(),
|
|
15260
|
-
packet: EncodedPacketSchema
|
|
15261
|
-
}), _void()), method(object({
|
|
15262
|
-
sessionId: string(),
|
|
15263
|
-
url: string()
|
|
15264
|
-
}), _void()), method(object({
|
|
15265
|
-
sessionId: string(),
|
|
15266
|
-
maxCount: number().default(1),
|
|
15267
|
-
waitMs: number().optional()
|
|
15268
|
-
}), array(DecodedFrameSchema)), method(object({
|
|
15269
|
-
sessionId: string(),
|
|
15270
|
-
maxCount: number().default(1),
|
|
15271
|
-
waitMs: number().optional()
|
|
15272
|
-
}), array(FrameHandleSchema)), method(object({ handle: FrameHandleSchema }), DecodedFrameSchema.nullable()), method(object({ sessionId: string() }), ShmRingStatsSchema.nullable()), method(object({
|
|
15273
|
-
sessionId: string(),
|
|
15274
|
-
config: DecoderSessionConfigSchema.partial()
|
|
15275
|
-
}), _void()), method(object({ sessionId: string() }), DecoderStatsSchema), method(_void(), array(object({
|
|
15276
|
-
sessionId: string(),
|
|
15277
|
-
codec: string(),
|
|
15278
|
-
outputFormat: string(),
|
|
15279
|
-
createdAtMs: number()
|
|
15280
|
-
})).readonly()), method(_void(), object({ backend: string() }), {
|
|
15075
|
+
})), method(_void(), object({ backend: string() }), {
|
|
15281
15076
|
kind: "mutation",
|
|
15282
15077
|
auth: "admin"
|
|
15283
15078
|
});
|
|
@@ -22347,8 +22142,8 @@ function interpretStoredClusterModel(raw) {
|
|
|
22347
22142
|
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
22348
22143
|
stepId: "face-embedding",
|
|
22349
22144
|
key: "minLandmarkFaceSize",
|
|
22350
|
-
label: "Min face size
|
|
22351
|
-
description: "
|
|
22145
|
+
label: "Min face size to embed (detection-frame px)",
|
|
22146
|
+
description: "Faces smaller than this in the small frame the detector sees are not embedded, so they can never be recognised. Below it the face cannot be aligned reliably and a bad embedding matches everyone. Same value on every node. 0 = no limit.",
|
|
22352
22147
|
type: "slider",
|
|
22353
22148
|
min: 0,
|
|
22354
22149
|
max: 64,
|
|
@@ -26480,14 +26275,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
26480
26275
|
* Per-inference-device live load (multi-device C4). One entry per deviceKey
|
|
26481
26276
|
* this runner currently has attached cameras on, so the orchestrator's second
|
|
26482
26277
|
* `balance()` pass (over a node's devices) weights on real per-pool session
|
|
26483
|
-
* counts. Empty on single-device / pre-multi-device runners.
|
|
26484
|
-
* per
|
|
26278
|
+
* counts. Empty on single-device / pre-multi-device runners. There is no
|
|
26279
|
+
* per-device queue depth: the inference pool's backlog has no accessor, and
|
|
26280
|
+
* a field that always read 0 was removed rather than shown as a measurement
|
|
26281
|
+
* (D762).
|
|
26485
26282
|
*/
|
|
26486
26283
|
devices: array(object({
|
|
26487
26284
|
deviceKey: string(),
|
|
26488
26285
|
backend: string(),
|
|
26489
|
-
attachedCameras: number()
|
|
26490
|
-
queueDepthTotal: number()
|
|
26286
|
+
attachedCameras: number()
|
|
26491
26287
|
})).default([]),
|
|
26492
26288
|
/** Hardware capability flags reported by this node. */
|
|
26493
26289
|
hardware: object({
|
|
@@ -26810,7 +26606,10 @@ var PipelineAssignmentSchema = object({
|
|
|
26810
26606
|
});
|
|
26811
26607
|
/**
|
|
26812
26608
|
* Per-agent load summary surfaced to the load balancer + dashboards.
|
|
26813
|
-
* Aggregated from each runner's `getLocalLoad` cap call.
|
|
26609
|
+
* Aggregated from each runner's `getLocalLoad` cap call. In the
|
|
26610
|
+
* `getAgentLoad` report, a single-device node's default-pool sessions (no
|
|
26611
|
+
* `deviceKey`) are credited to its one eligible device in `load.devices` —
|
|
26612
|
+
* the default pool IS that device (D745); the balancer's census stays raw.
|
|
26814
26613
|
*/
|
|
26815
26614
|
var AgentLoadSummarySchema = object({
|
|
26816
26615
|
nodeId: string(),
|
|
@@ -26899,8 +26698,14 @@ var CameraBrokerStatusSchema = object({
|
|
|
26899
26698
|
width: number(),
|
|
26900
26699
|
height: number(),
|
|
26901
26700
|
subscribers: number(),
|
|
26902
|
-
|
|
26903
|
-
|
|
26701
|
+
/**
|
|
26702
|
+
* Encoded packets/s the broker receives from the camera. null when the
|
|
26703
|
+
* broker's stats read failed — unknown, never 0 (a 0 here reads as a stall).
|
|
26704
|
+
* There is no output rate: decoding runs in the session decode workers, not
|
|
26705
|
+
* in the broker, so the broker's own decoded-frame rate is 0 on every live
|
|
26706
|
+
* camera and is not served (D758).
|
|
26707
|
+
*/
|
|
26708
|
+
inFps: number().nullable()
|
|
26904
26709
|
})).readonly(),
|
|
26905
26710
|
webrtcSessions: number(),
|
|
26906
26711
|
rtspRestream: boolean()
|
|
@@ -29989,8 +29794,6 @@ var WebrtcStreamChoiceSchema = object({
|
|
|
29989
29794
|
]).nullable(),
|
|
29990
29795
|
/** Input FPS from the camera (null for adaptive). */
|
|
29991
29796
|
inputFps: number().nullable(),
|
|
29992
|
-
/** Decoded FPS (null for adaptive). */
|
|
29993
|
-
decodeFps: number().nullable(),
|
|
29994
29797
|
/** Bitrate in kbps (null for adaptive). */
|
|
29995
29798
|
bitrateKbps: number().nullable()
|
|
29996
29799
|
});
|
|
@@ -40236,90 +40039,18 @@ Object.freeze({
|
|
|
40236
40039
|
addonId: null,
|
|
40237
40040
|
access: "create"
|
|
40238
40041
|
},
|
|
40239
|
-
"decoder.createSession": {
|
|
40240
|
-
capName: "decoder",
|
|
40241
|
-
capScope: "system",
|
|
40242
|
-
addonId: null,
|
|
40243
|
-
access: "view"
|
|
40244
|
-
},
|
|
40245
|
-
"decoder.destroySession": {
|
|
40246
|
-
capName: "decoder",
|
|
40247
|
-
capScope: "system",
|
|
40248
|
-
addonId: null,
|
|
40249
|
-
access: "delete"
|
|
40250
|
-
},
|
|
40251
|
-
"decoder.getFrame": {
|
|
40252
|
-
capName: "decoder",
|
|
40253
|
-
capScope: "system",
|
|
40254
|
-
addonId: null,
|
|
40255
|
-
access: "view"
|
|
40256
|
-
},
|
|
40257
40042
|
"decoder.getInfo": {
|
|
40258
40043
|
capName: "decoder",
|
|
40259
40044
|
capScope: "system",
|
|
40260
40045
|
addonId: null,
|
|
40261
40046
|
access: "view"
|
|
40262
40047
|
},
|
|
40263
|
-
"decoder.getShmStats": {
|
|
40264
|
-
capName: "decoder",
|
|
40265
|
-
capScope: "system",
|
|
40266
|
-
addonId: null,
|
|
40267
|
-
access: "view"
|
|
40268
|
-
},
|
|
40269
|
-
"decoder.getStats": {
|
|
40270
|
-
capName: "decoder",
|
|
40271
|
-
capScope: "system",
|
|
40272
|
-
addonId: null,
|
|
40273
|
-
access: "view"
|
|
40274
|
-
},
|
|
40275
|
-
"decoder.listActiveSessions": {
|
|
40276
|
-
capName: "decoder",
|
|
40277
|
-
capScope: "system",
|
|
40278
|
-
addonId: null,
|
|
40279
|
-
access: "view"
|
|
40280
|
-
},
|
|
40281
|
-
"decoder.openStream": {
|
|
40282
|
-
capName: "decoder",
|
|
40283
|
-
capScope: "system",
|
|
40284
|
-
addonId: null,
|
|
40285
|
-
access: "view"
|
|
40286
|
-
},
|
|
40287
|
-
"decoder.pullFrames": {
|
|
40288
|
-
capName: "decoder",
|
|
40289
|
-
capScope: "system",
|
|
40290
|
-
addonId: null,
|
|
40291
|
-
access: "view"
|
|
40292
|
-
},
|
|
40293
|
-
"decoder.pullHandles": {
|
|
40294
|
-
capName: "decoder",
|
|
40295
|
-
capScope: "system",
|
|
40296
|
-
addonId: null,
|
|
40297
|
-
access: "view"
|
|
40298
|
-
},
|
|
40299
|
-
"decoder.pushPacket": {
|
|
40300
|
-
capName: "decoder",
|
|
40301
|
-
capScope: "system",
|
|
40302
|
-
addonId: null,
|
|
40303
|
-
access: "view"
|
|
40304
|
-
},
|
|
40305
40048
|
"decoder.reprobeHwaccel": {
|
|
40306
40049
|
capName: "decoder",
|
|
40307
40050
|
capScope: "system",
|
|
40308
40051
|
addonId: null,
|
|
40309
40052
|
access: "create"
|
|
40310
40053
|
},
|
|
40311
|
-
"decoder.supportsCodec": {
|
|
40312
|
-
capName: "decoder",
|
|
40313
|
-
capScope: "system",
|
|
40314
|
-
addonId: null,
|
|
40315
|
-
access: "view"
|
|
40316
|
-
},
|
|
40317
|
-
"decoder.updateConfig": {
|
|
40318
|
-
capName: "decoder",
|
|
40319
|
-
capScope: "system",
|
|
40320
|
-
addonId: null,
|
|
40321
|
-
access: "view"
|
|
40322
|
-
},
|
|
40323
40054
|
"detectionPipeline.applyDeviceSettingsPatch": {
|
|
40324
40055
|
capName: "detection-pipeline",
|
|
40325
40056
|
capScope: "device",
|
|
@@ -45366,12 +45097,6 @@ Object.freeze({
|
|
|
45366
45097
|
addonId: null,
|
|
45367
45098
|
access: "view"
|
|
45368
45099
|
},
|
|
45369
|
-
"streamBroker.pullFrameHandles": {
|
|
45370
|
-
capName: "stream-broker",
|
|
45371
|
-
capScope: "system",
|
|
45372
|
-
addonId: null,
|
|
45373
|
-
access: "view"
|
|
45374
|
-
},
|
|
45375
45100
|
"streamBroker.regenerateRtspToken": {
|
|
45376
45101
|
capName: "stream-broker",
|
|
45377
45102
|
capScope: "system",
|
|
@@ -45438,12 +45163,6 @@ Object.freeze({
|
|
|
45438
45163
|
addonId: null,
|
|
45439
45164
|
access: "create"
|
|
45440
45165
|
},
|
|
45441
|
-
"streamBroker.subscribeFrames": {
|
|
45442
|
-
capName: "stream-broker",
|
|
45443
|
-
capScope: "system",
|
|
45444
|
-
addonId: null,
|
|
45445
|
-
access: "create"
|
|
45446
|
-
},
|
|
45447
45166
|
"streamBroker.unassignProfile": {
|
|
45448
45167
|
capName: "stream-broker",
|
|
45449
45168
|
capScope: "system",
|
|
@@ -45456,12 +45175,6 @@ Object.freeze({
|
|
|
45456
45175
|
addonId: null,
|
|
45457
45176
|
access: "create"
|
|
45458
45177
|
},
|
|
45459
|
-
"streamBroker.unsubscribeFrames": {
|
|
45460
|
-
capName: "stream-broker",
|
|
45461
|
-
capScope: "system",
|
|
45462
|
-
addonId: null,
|
|
45463
|
-
access: "create"
|
|
45464
|
-
},
|
|
45465
45178
|
"streamCatalog.getCatalog": {
|
|
45466
45179
|
capName: "stream-catalog",
|
|
45467
45180
|
capScope: "device",
|
|
@@ -48003,11 +47716,6 @@ Object.freeze({
|
|
|
48003
47716
|
form: "single",
|
|
48004
47717
|
optional: false
|
|
48005
47718
|
}],
|
|
48006
|
-
"decoder.createSession": [{
|
|
48007
|
-
name: "deviceId",
|
|
48008
|
-
form: "single",
|
|
48009
|
-
optional: true
|
|
48010
|
-
}],
|
|
48011
47719
|
"detectionPipeline.applyDeviceSettingsPatch": [{
|
|
48012
47720
|
name: "deviceId",
|
|
48013
47721
|
form: "single",
|
|
@@ -54724,6 +54432,40 @@ var LoadShedController = class LoadShedController {
|
|
|
54724
54432
|
}
|
|
54725
54433
|
};
|
|
54726
54434
|
//#endregion
|
|
54435
|
+
//#region src/default-pool-attribution.ts
|
|
54436
|
+
/** The backend prefix of a `<backend>:<device>` key (bare `cpu` → `cpu`). */
|
|
54437
|
+
function backendOf(deviceKey) {
|
|
54438
|
+
const colon = deviceKey.indexOf(":");
|
|
54439
|
+
return colon >= 0 ? deviceKey.slice(0, colon) : deviceKey;
|
|
54440
|
+
}
|
|
54441
|
+
/**
|
|
54442
|
+
* `load` with its unattributed sessions credited to `eligibleKeys[0]` when that
|
|
54443
|
+
* is the node's ONLY eligible device; `load` itself (same reference) otherwise.
|
|
54444
|
+
* `eligibleKeys` null = the eligible set is not known.
|
|
54445
|
+
*/
|
|
54446
|
+
function attributeDefaultPoolSessions(load, eligibleKeys) {
|
|
54447
|
+
if (eligibleKeys === null || eligibleKeys.length !== 1) return load;
|
|
54448
|
+
const onlyKey = eligibleKeys[0];
|
|
54449
|
+
if (onlyKey === void 0) return load;
|
|
54450
|
+
const attributed = load.devices.reduce((sum, d) => sum + d.attachedCameras, 0);
|
|
54451
|
+
const unattributed = load.attachedCameras - attributed;
|
|
54452
|
+
if (unattributed <= 0) return load;
|
|
54453
|
+
const existing = load.devices.find((d) => d.deviceKey === onlyKey);
|
|
54454
|
+
const credited = existing ? {
|
|
54455
|
+
...existing,
|
|
54456
|
+
attachedCameras: existing.attachedCameras + unattributed
|
|
54457
|
+
} : {
|
|
54458
|
+
deviceKey: onlyKey,
|
|
54459
|
+
backend: backendOf(onlyKey),
|
|
54460
|
+
attachedCameras: unattributed
|
|
54461
|
+
};
|
|
54462
|
+
const devices = [...load.devices.filter((d) => d.deviceKey !== onlyKey), credited].toSorted((a, b) => a.deviceKey.localeCompare(b.deviceKey));
|
|
54463
|
+
return {
|
|
54464
|
+
...load,
|
|
54465
|
+
devices
|
|
54466
|
+
};
|
|
54467
|
+
}
|
|
54468
|
+
//#endregion
|
|
54727
54469
|
//#region src/dispatch-timing.ts
|
|
54728
54470
|
/**
|
|
54729
54471
|
* How long the placement census waits for ONE runner's `getLocalCameras`
|
|
@@ -54790,6 +54532,25 @@ var AgentLoadService = class AgentLoadService {
|
|
|
54790
54532
|
getAgentLoadSummaries() {
|
|
54791
54533
|
return [...this.cachedAgentLoad.values()];
|
|
54792
54534
|
}
|
|
54535
|
+
/**
|
|
54536
|
+
* The cached summaries as the load REPORT (`getAgentLoad`) carries them: a
|
|
54537
|
+
* single-device node's default-pool sessions credited to its one device
|
|
54538
|
+
* (`default-pool-attribution.ts`). The balancer's census
|
|
54539
|
+
* ({@link collectAgentLoad}) stays the runner's raw answer.
|
|
54540
|
+
*/
|
|
54541
|
+
async reportedAgentLoad() {
|
|
54542
|
+
const resolve = this.deps.eligibleDeviceKeys;
|
|
54543
|
+
const summaries = this.getAgentLoadSummaries();
|
|
54544
|
+
if (resolve === void 0) return summaries;
|
|
54545
|
+
return Promise.all(summaries.map(async (summary) => {
|
|
54546
|
+
const eligible = await resolve(summary.nodeId).catch(() => null);
|
|
54547
|
+
const load = attributeDefaultPoolSessions(summary.load, eligible);
|
|
54548
|
+
return load === summary.load ? summary : {
|
|
54549
|
+
...summary,
|
|
54550
|
+
load
|
|
54551
|
+
};
|
|
54552
|
+
}));
|
|
54553
|
+
}
|
|
54793
54554
|
cachedAgentLoadNodeIds() {
|
|
54794
54555
|
return [...this.cachedAgentLoad.keys()];
|
|
54795
54556
|
}
|
|
@@ -57237,8 +56998,7 @@ function mapBroker(brokerResult) {
|
|
|
57237
56998
|
width: p.width,
|
|
57238
56999
|
height: p.height,
|
|
57239
57000
|
subscribers: p.subscribers,
|
|
57240
|
-
inFps: p.inFps
|
|
57241
|
-
outFps: p.outFps
|
|
57001
|
+
inFps: p.inFps
|
|
57242
57002
|
})),
|
|
57243
57003
|
webrtcSessions: brokerResult.webrtcSessions,
|
|
57244
57004
|
rtspRestream: brokerResult.rtspRestream
|
|
@@ -57625,11 +57385,9 @@ var CameraStatusService = class {
|
|
|
57625
57385
|
* `allSlotsFetch` (fetched once by the caller) to avoid a second
|
|
57626
57386
|
* round-trip. Per-slot `getBrokerStats` + `listClients` are fetched in
|
|
57627
57387
|
* parallel. WebRTC sessions are counted by filtering `encoded[]` entries
|
|
57628
|
-
* whose `attribution.kind` is one of the `WEBRTC_KINDS`.
|
|
57629
|
-
* broker's actual decode-session node into `liveDecoder` (T6) — the first
|
|
57630
|
-
* slot that reports one wins.
|
|
57388
|
+
* whose `attribution.kind` is one of the `WEBRTC_KINDS`.
|
|
57631
57389
|
*/
|
|
57632
|
-
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57390
|
+
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, sink) {
|
|
57633
57391
|
if (!api || !allSlotsFetch) return Promise.resolve(null);
|
|
57634
57392
|
return this.boundedStage(allSlotsFetch.then(async (slots) => {
|
|
57635
57393
|
const deviceSlots = slots.filter((s) => s.deviceId === deviceId);
|
|
@@ -57646,19 +57404,16 @@ var CameraStatusService = class {
|
|
|
57646
57404
|
clients
|
|
57647
57405
|
};
|
|
57648
57406
|
})), pass.rtspEntries(api, sourceNodeId).catch(() => null)]);
|
|
57649
|
-
const profileDetails = statsAndClients.map(({ slot, stats, clients }) => ({
|
|
57650
|
-
profile: slot.profile,
|
|
57651
|
-
status: slot.status,
|
|
57652
|
-
codec: stats?.codec ?? slot.codec ?? "",
|
|
57653
|
-
width: slot.resolution?.width ?? 0,
|
|
57654
|
-
height: slot.resolution?.height ?? 0,
|
|
57655
|
-
subscribers: clients?.encodedSubscribers ?? 0,
|
|
57656
|
-
inFps: stats?.inputFps ?? 0,
|
|
57657
|
-
outFps: stats?.decodeFps ?? 0
|
|
57658
|
-
}));
|
|
57659
|
-
for (const { stats } of statsAndClients) if (liveDecoder.nodeId === null && typeof stats?.decoderNodeId === "string") liveDecoder.nodeId = stats.decoderNodeId;
|
|
57660
57407
|
return {
|
|
57661
|
-
profiles:
|
|
57408
|
+
profiles: statsAndClients.map(({ slot, stats, clients }) => ({
|
|
57409
|
+
profile: slot.profile,
|
|
57410
|
+
status: slot.status,
|
|
57411
|
+
codec: stats?.codec ?? slot.codec ?? "",
|
|
57412
|
+
width: slot.resolution?.width ?? 0,
|
|
57413
|
+
height: slot.resolution?.height ?? 0,
|
|
57414
|
+
subscribers: clients?.encodedSubscribers ?? 0,
|
|
57415
|
+
inFps: stats?.inputFps ?? null
|
|
57416
|
+
})),
|
|
57662
57417
|
webrtcSessions: statsAndClients.reduce((total, { clients }) => {
|
|
57663
57418
|
if (!clients) return total;
|
|
57664
57419
|
return total + clients.encoded.filter((c) => WEBRTC_KINDS.has(c.attribution.kind)).length;
|
|
@@ -57852,10 +57607,9 @@ var CameraStatusService = class {
|
|
|
57852
57607
|
const api = this.deps.api();
|
|
57853
57608
|
const degradations = { entries: [] };
|
|
57854
57609
|
const { detectionNodeId, sourceNodeId, pinned, detectionReason, audioNodeId, audioPinned } = this.buildAssignmentContext(deviceId);
|
|
57855
|
-
const liveDecoder = { nodeId: null };
|
|
57856
57610
|
const allSlotsFetch = api ? pass.profileSlots(api, sourceNodeId) : null;
|
|
57857
57611
|
const sourceFetch = this.buildSourceStage(api, allSlotsFetch, deviceId, degradations);
|
|
57858
|
-
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57612
|
+
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, degradations);
|
|
57859
57613
|
const decoderFetch = this.buildDecoderStage(detectionNodeId);
|
|
57860
57614
|
const motionResult = this.buildMotionStage(deviceId);
|
|
57861
57615
|
const detectionFetch = this.buildDetectionStage(api, detectionNodeId, deviceId, pass, degradations);
|
|
@@ -57870,11 +57624,10 @@ var CameraStatusService = class {
|
|
|
57870
57624
|
switchesFetch
|
|
57871
57625
|
]);
|
|
57872
57626
|
const audioResult = this.buildAudioStage(audioNodeId, switchedOff);
|
|
57873
|
-
const
|
|
57874
|
-
const decoderNodeId = liveDecoderNodeId ?? detectionNodeId;
|
|
57627
|
+
const decoderNodeId = detectionNodeId;
|
|
57875
57628
|
const reasons = {
|
|
57876
57629
|
detection: detectionReason,
|
|
57877
|
-
decoder:
|
|
57630
|
+
decoder: decoderNodeId !== null ? "co-located" : void 0,
|
|
57878
57631
|
audio: audioPinned ? "manual" : void 0
|
|
57879
57632
|
};
|
|
57880
57633
|
return composeCameraStatus({
|
|
@@ -60111,7 +59864,7 @@ function deviceAsLoad(deviceKey, load) {
|
|
|
60111
59864
|
activeCameras: 0,
|
|
60112
59865
|
avgInferenceFps: 0,
|
|
60113
59866
|
avgInferenceTimeMs: 0,
|
|
60114
|
-
queueDepthTotal:
|
|
59867
|
+
queueDepthTotal: 0,
|
|
60115
59868
|
devices: [],
|
|
60116
59869
|
hardware: { hasGpu: false }
|
|
60117
59870
|
};
|
|
@@ -61091,8 +60844,7 @@ function tallyLoad(load, nodeDelta, perDevice) {
|
|
|
61091
60844
|
}), ...[...perDevice ?? /* @__PURE__ */ new Map()].filter(([deviceKey, delta]) => !known.has(deviceKey) && delta > 0).map(([deviceKey, delta]) => ({
|
|
61092
60845
|
deviceKey,
|
|
61093
60846
|
backend: deviceKey.split(":")[0] ?? deviceKey,
|
|
61094
|
-
attachedCameras: delta
|
|
61095
|
-
queueDepthTotal: 0
|
|
60847
|
+
attachedCameras: delta
|
|
61096
60848
|
}))];
|
|
61097
60849
|
return {
|
|
61098
60850
|
...load,
|
|
@@ -69080,6 +68832,10 @@ async function buildOrchestratorControllers(deps) {
|
|
|
69080
68832
|
onCensus: (entries) => {
|
|
69081
68833
|
motionSliceGate?.noteCensus(entries);
|
|
69082
68834
|
providerSliceGate?.refreshIfStale("runner-census");
|
|
68835
|
+
},
|
|
68836
|
+
eligibleDeviceKeys: async (nodeId) => {
|
|
68837
|
+
const read = await deps.getEligibleInferenceDevicesIfCached(nodeId);
|
|
68838
|
+
return read.kind === "eligible" ? Object.keys(read.eligible) : null;
|
|
69083
68839
|
}
|
|
69084
68840
|
});
|
|
69085
68841
|
/**
|
|
@@ -69938,12 +69694,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
69938
69694
|
id: CLUSTER_MODEL_SECTION_ID,
|
|
69939
69695
|
title: "Enrichment models",
|
|
69940
69696
|
tab: "pipeline",
|
|
69941
|
-
description: "The
|
|
69697
|
+
description: "The face and search encoders, one each for the whole cluster: each fills a single shared index, and vectors from two models cannot be compared. Changing one keeps what is stored but hides it from matching and search until it is re-embedded.",
|
|
69942
69698
|
fields: [...CLUSTER_MODEL_SCOPED_STEPS.map((step) => ({
|
|
69943
69699
|
key: clusterModelSettingKey(step.stepId),
|
|
69944
69700
|
type: "select",
|
|
69945
69701
|
label: step.label,
|
|
69946
|
-
description: `
|
|
69702
|
+
description: `Used on every node. A node that has no build of this model skips the step (and logs it) rather than use another model. Changing it hides what is already in ${step.indexName} until it is re-embedded.`,
|
|
69947
69703
|
options: step.options.map((o) => ({
|
|
69948
69704
|
value: o.id,
|
|
69949
69705
|
label: o.label
|
|
@@ -69965,12 +69721,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
69965
69721
|
id: DETAIL_CROP_SECTION_ID,
|
|
69966
69722
|
title: "Enrichment crop",
|
|
69967
69723
|
tab: "pipeline",
|
|
69968
|
-
description: "How the crop
|
|
69724
|
+
description: "How the crop handed to the search, face and plate models is cut from the frame. One value for the whole cluster, because search results are only comparable when every crop is cut the same way. After changing it, rebuild the search index (Camera → Semantic search index → Rebuild).",
|
|
69969
69725
|
fields: [{
|
|
69970
69726
|
key: DETAIL_CROP_PADDING_KEY,
|
|
69971
69727
|
type: "slider",
|
|
69972
69728
|
label: "Crop margin",
|
|
69973
|
-
description: "
|
|
69729
|
+
description: "Extra margin added on each side of the detection box, as a fraction of its size. 0 = tight box, 0.15 = default. Search works better with some surroundings in the crop.",
|
|
69974
69730
|
min: DETAIL_CROP_PADDING_FIELD.min,
|
|
69975
69731
|
max: DETAIL_CROP_PADDING_FIELD.max,
|
|
69976
69732
|
step: DETAIL_CROP_PADDING_FIELD.step,
|
|
@@ -69980,7 +69736,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
69980
69736
|
key: DETAIL_CROP_SQUARE_KEY,
|
|
69981
69737
|
type: "boolean",
|
|
69982
69738
|
label: "Square the crop",
|
|
69983
|
-
description: "
|
|
69739
|
+
description: "Widen the crop to a square so a tall subject is not squashed when the model resizes it. Off by default because the existing index was built without it.",
|
|
69984
69740
|
default: DEFAULT_DETAIL_CROP_CONVENTION.square
|
|
69985
69741
|
}]
|
|
69986
69742
|
},
|
|
@@ -69988,13 +69744,13 @@ function buildGlobalSettingsSections(options) {
|
|
|
69988
69744
|
id: NATIVE_LEASE_SECTION_ID,
|
|
69989
69745
|
title: "Native frame lease",
|
|
69990
69746
|
tab: "pipeline",
|
|
69991
|
-
description: "How
|
|
69747
|
+
description: "How each camera keeps full-resolution pixels so a crop taken seconds later (snapshot, face, plate) is sharp instead of cut from the small detection frame. A held frame is a whole picture (~25 MB at 4K) kept until its detections arrive; a tile is one subject, or one whole-scene copy, saved as JPEG for tens of seconds. Applies from the next session of each camera.",
|
|
69992
69748
|
fields: [
|
|
69993
69749
|
{
|
|
69994
69750
|
key: NATIVE_LEASE_HOLD_KEY,
|
|
69995
69751
|
type: "slider",
|
|
69996
69752
|
label: "Frames held at once",
|
|
69997
|
-
description: "
|
|
69753
|
+
description: "Most frames kept per camera while their detections are pending; past it the oldest is dropped. 1 to 4 are in use normally. Raise it only if a slow node drops frames (holdOverflow in the logs) — it does not make crops sharper.",
|
|
69998
69754
|
min: NATIVE_LEASE_HOLD_FIELD.min,
|
|
69999
69755
|
max: NATIVE_LEASE_HOLD_FIELD.max,
|
|
70000
69756
|
step: NATIVE_LEASE_HOLD_FIELD.step,
|
|
@@ -70006,7 +69762,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70006
69762
|
key: NATIVE_LEASE_TILE_BUDGET_KEY,
|
|
70007
69763
|
type: "slider",
|
|
70008
69764
|
label: "Subject tile RAM",
|
|
70009
|
-
description: "RAM per
|
|
69765
|
+
description: "RAM per camera for subject tiles: full-resolution crops of each detected subject, kept so a crop asked for seconds later is still sharp. A tile is ~60-120 KB. 0 = off (late crops come from the small detection frame).",
|
|
70010
69766
|
min: NATIVE_LEASE_TILE_BUDGET_FIELD.min,
|
|
70011
69767
|
max: NATIVE_LEASE_TILE_BUDGET_FIELD.max,
|
|
70012
69768
|
step: NATIVE_LEASE_TILE_BUDGET_FIELD.step,
|
|
@@ -70018,7 +69774,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70018
69774
|
key: NATIVE_LEASE_SCENE_BUDGET_KEY,
|
|
70019
69775
|
type: "slider",
|
|
70020
69776
|
label: "Scene tile RAM",
|
|
70021
|
-
description: "RAM per
|
|
69777
|
+
description: "RAM per camera for scene tiles: a full-resolution JPEG of the whole picture (~2 MB at 4K) on frames where something was detected, for key frames and whole-frame crops. 0 = off (those then fall back to the small detection frame).",
|
|
70022
69778
|
min: NATIVE_LEASE_SCENE_BUDGET_FIELD.min,
|
|
70023
69779
|
max: NATIVE_LEASE_SCENE_BUDGET_FIELD.max,
|
|
70024
69780
|
step: NATIVE_LEASE_SCENE_BUDGET_FIELD.step,
|
|
@@ -70030,7 +69786,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70030
69786
|
key: NATIVE_LEASE_BUDGET_KEY,
|
|
70031
69787
|
type: "slider",
|
|
70032
69788
|
label: "Lease RAM ceiling",
|
|
70033
|
-
description: "
|
|
69789
|
+
description: "Safety ceiling on the RAM held frames may use per camera; the frame count above is what normally limits it. Lower it on a small host. 0 turns full-resolution crops off almost entirely — for diagnosis only.",
|
|
70034
69790
|
min: NATIVE_LEASE_BUDGET_FIELD.min,
|
|
70035
69791
|
max: NATIVE_LEASE_BUDGET_FIELD.max,
|
|
70036
69792
|
step: NATIVE_LEASE_BUDGET_FIELD.step,
|
|
@@ -70042,7 +69798,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70042
69798
|
key: NATIVE_LEASE_ACTIVITY_KEY,
|
|
70043
69799
|
type: "slider",
|
|
70044
69800
|
label: "Demand window",
|
|
70045
|
-
description: "
|
|
69801
|
+
description: "Keep full-resolution pixels only within this long of the last crop request, so a camera nobody crops costs nothing; the first crop after a quiet spell falls back once. 0 = always keep (heavy on small hosts).",
|
|
70046
69802
|
min: NATIVE_LEASE_ACTIVITY_FIELD.min,
|
|
70047
69803
|
max: NATIVE_LEASE_ACTIVITY_FIELD.max,
|
|
70048
69804
|
step: NATIVE_LEASE_ACTIVITY_FIELD.step,
|
|
@@ -70055,7 +69811,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70055
69811
|
key: NATIVE_LEASE_ADMISSION_KEY,
|
|
70056
69812
|
type: "select",
|
|
70057
69813
|
label: "What to retain",
|
|
70058
|
-
description: "
|
|
69814
|
+
description: "Which frames get a full-resolution copy. 'Only frames sent to inference' keeps the frames a crop can actually ask for (about 80% less RAM); 'Every delivered frame' keeps all of them.",
|
|
70059
69815
|
options: NATIVE_LEASE_ADMISSION_FIELD.options,
|
|
70060
69816
|
default: NATIVE_LEASE_ADMISSION_FIELD.default
|
|
70061
69817
|
}
|
|
@@ -70068,7 +69824,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70068
69824
|
{
|
|
70069
69825
|
key: "onDisconnect",
|
|
70070
69826
|
type: "select",
|
|
70071
|
-
label: "
|
|
69827
|
+
label: "When a node disconnects",
|
|
69828
|
+
description: "Move its unpinned cameras to other nodes, or leave them stopped.",
|
|
70072
69829
|
default: DEFAULT_FAILOVER_POLICY.onDisconnect,
|
|
70073
69830
|
options: [{
|
|
70074
69831
|
value: "migrate",
|
|
@@ -70081,7 +69838,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70081
69838
|
{
|
|
70082
69839
|
key: "pinnedOnDisconnect",
|
|
70083
69840
|
type: "select",
|
|
70084
|
-
label: "
|
|
69841
|
+
label: "Its pinned cameras",
|
|
69842
|
+
description: "Keep the pin and wait for the node, or drop the pin and move them.",
|
|
70085
69843
|
default: DEFAULT_FAILOVER_POLICY.pinnedOnDisconnect,
|
|
70086
69844
|
options: [{
|
|
70087
69845
|
value: "leave-pinned",
|
|
@@ -70094,7 +69852,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70094
69852
|
{
|
|
70095
69853
|
key: "onReconnect",
|
|
70096
69854
|
type: "select",
|
|
70097
|
-
label: "
|
|
69855
|
+
label: "When it comes back",
|
|
69856
|
+
description: "Put its cameras back where they were, or rebalance the whole cluster.",
|
|
70098
69857
|
default: DEFAULT_FAILOVER_POLICY.onReconnect,
|
|
70099
69858
|
options: [{
|
|
70100
69859
|
value: "restore",
|
|
@@ -72095,7 +71854,7 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
72095
71854
|
async getAgentLoad() {
|
|
72096
71855
|
await this.loadService.refreshDecodeHwaccels();
|
|
72097
71856
|
await this.loadService.collectAgentLoad();
|
|
72098
|
-
return this.loadService.
|
|
71857
|
+
return this.loadService.reportedAgentLoad();
|
|
72099
71858
|
}
|
|
72100
71859
|
async getGlobalMetrics() {
|
|
72101
71860
|
const summaries = await this.getAgentLoad();
|