@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.js
CHANGED
|
@@ -30,7 +30,7 @@ node_fs = __toESM(node_fs);
|
|
|
30
30
|
let node_path = require("node:path");
|
|
31
31
|
node_path = __toESM(node_path);
|
|
32
32
|
let node_url = require("node:url");
|
|
33
|
-
//#region ../types/dist/event-category-
|
|
33
|
+
//#region ../types/dist/event-category-B_0XEcLF.mjs
|
|
34
34
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
35
35
|
EventCategory["SystemBoot"] = "system.boot";
|
|
36
36
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -531,15 +531,6 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
531
531
|
EventCategory["AgentWsDisconnected"] = "agent.ws.disconnected";
|
|
532
532
|
EventCategory["AgentBackupActivated"] = "agent.backup.activated";
|
|
533
533
|
EventCategory["OrchestrationSettingsUpdated"] = "orchestration.settings-updated";
|
|
534
|
-
/**
|
|
535
|
-
* Per-agent hwaccel preference changed (user override set, cleared, or
|
|
536
|
-
* re-probed). Observability event — decoders pull the current pref at
|
|
537
|
-
* `createSession`, so running sessions keep their current backend until
|
|
538
|
-
* they rotate naturally (camera add/remove, stream restart). Future
|
|
539
|
-
* work can wire a listener in stream-broker that force-rotates live
|
|
540
|
-
* sessions; for now this event powers logs + admin-UI toast feedback.
|
|
541
|
-
*/
|
|
542
|
-
EventCategory["PipelineAgentHwaccelChanged"] = "pipeline.agent-hwaccel-changed";
|
|
543
534
|
EventCategory["MotionAnalysis"] = "detection.motion-analysis";
|
|
544
535
|
/** All raw motion zones from CCL before minArea filter — for UI debug overlay. */
|
|
545
536
|
EventCategory["MotionZonesRaw"] = "detection.motion-zones-raw";
|
|
@@ -5410,7 +5401,7 @@ var ZodIssueCode = {
|
|
|
5410
5401
|
var ZodFirstPartyTypeKind;
|
|
5411
5402
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5412
5403
|
//#endregion
|
|
5413
|
-
//#region ../types/dist/sleep-
|
|
5404
|
+
//#region ../types/dist/sleep-BNeXenvr.mjs
|
|
5414
5405
|
/**
|
|
5415
5406
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5416
5407
|
* window to float samples (D455).
|
|
@@ -6809,32 +6800,12 @@ object({
|
|
|
6809
6800
|
audioCodec: string().optional(),
|
|
6810
6801
|
metadata: record(string(), unknown()).readonly().optional()
|
|
6811
6802
|
});
|
|
6812
|
-
var EncodedPacketSchema = object({
|
|
6813
|
-
type: _enum(["video", "audio"]),
|
|
6814
|
-
data: _instanceof(Uint8Array),
|
|
6815
|
-
pts: number(),
|
|
6816
|
-
dts: number(),
|
|
6817
|
-
keyframe: boolean(),
|
|
6818
|
-
codec: string()
|
|
6819
|
-
});
|
|
6820
|
-
var DecodedFrameSchema = object({
|
|
6821
|
-
data: _instanceof(Uint8Array),
|
|
6822
|
-
width: number(),
|
|
6823
|
-
height: number(),
|
|
6824
|
-
format: _enum([
|
|
6825
|
-
"jpeg",
|
|
6826
|
-
"rgb",
|
|
6827
|
-
"bgr",
|
|
6828
|
-
"yuv420",
|
|
6829
|
-
"gray"
|
|
6830
|
-
]),
|
|
6831
|
-
timestamp: number()
|
|
6832
|
-
});
|
|
6833
6803
|
/**
|
|
6834
6804
|
* Wire schema for `FrameHandle` — a zero-pixel, serialisable reference to a
|
|
6835
6805
|
* frame in a shared-memory ring (Phase 5 / D9). Mirrors the `FrameHandle` TS
|
|
6836
|
-
* interface in `interfaces/frame-handle.ts` field-for-field so a
|
|
6837
|
-
*
|
|
6806
|
+
* interface in `interfaces/frame-handle.ts` field-for-field so a cap method
|
|
6807
|
+
* (the runner's native-crop and pipeline-executor inputs) can carry handles
|
|
6808
|
+
* over tRPC / Moleculer.
|
|
6838
6809
|
*
|
|
6839
6810
|
* The `satisfies` assertion below pins this schema to the interface: if a
|
|
6840
6811
|
* field is added to / removed from `FrameHandle` without a matching schema
|
|
@@ -6860,50 +6831,6 @@ var FrameHandleSchema = object({
|
|
|
6860
6831
|
slotCount: number().int().positive()
|
|
6861
6832
|
});
|
|
6862
6833
|
/**
|
|
6863
|
-
* Pixel format a frame-handle subscriber can request from the broker
|
|
6864
|
-
* (Phase 5 / D9). The packed, raster subset of `FrameFormat` — the formats a
|
|
6865
|
-
* `frameSink: 'shm'` decoder session can write into a `FrameRing` slot.
|
|
6866
|
-
* `jpeg` is excluded: a variable-length stream is not a fixed-stride ring
|
|
6867
|
-
* payload, and no decoded-frame consumer requests it over the shm plane.
|
|
6868
|
-
*/
|
|
6869
|
-
var FrameHandleFormatSchema = _enum([
|
|
6870
|
-
"rgb",
|
|
6871
|
-
"bgr",
|
|
6872
|
-
"yuv420",
|
|
6873
|
-
"gray"
|
|
6874
|
-
]);
|
|
6875
|
-
/**
|
|
6876
|
-
* Input for `stream-broker.subscribeFrames` (Phase 5 / D9). A consumer asks the
|
|
6877
|
-
* broker for a `FrameHandle` stream of one `format`; the broker maintains one
|
|
6878
|
-
* shared-memory ring per `(brokerId, format)` actually requested, so a `gray`
|
|
6879
|
-
* subscriber (motion) and an `rgb` subscriber (detection) each read the format
|
|
6880
|
-
* they asked for with no broker-side conversion.
|
|
6881
|
-
*/
|
|
6882
|
-
var SubscribeFramesInputSchema = object({
|
|
6883
|
-
brokerId: string(),
|
|
6884
|
-
format: FrameHandleFormatSchema,
|
|
6885
|
-
/**
|
|
6886
|
-
* Optional reader-side cadence hint in frames per second. The broker does
|
|
6887
|
-
* NOT throttle — latest-wins ring reads drop frames implicitly for a slow
|
|
6888
|
-
* consumer. The value is echoed back in `SubscribeFramesResult.maxFps` so
|
|
6889
|
-
* the consumer can pace its own `pullFrameHandles` polling.
|
|
6890
|
-
*/
|
|
6891
|
-
maxFps: number().positive().optional(),
|
|
6892
|
-
/** Short caller-identity tag (`motion`, `detection`, …) for diagnostics. */
|
|
6893
|
-
tag: string().optional()
|
|
6894
|
-
});
|
|
6895
|
-
/**
|
|
6896
|
-
* Result of `stream-broker.subscribeFrames`. The consumer then polls
|
|
6897
|
-
* `pullFrameHandles({ subscriptionId, maxCount })` and feeds each returned
|
|
6898
|
-
* `FrameHandle` to a `FrameRingReader`.
|
|
6899
|
-
*/
|
|
6900
|
-
var SubscribeFramesResultSchema = object({
|
|
6901
|
-
/** Opaque id the consumer passes to `pullFrameHandles` / `unsubscribeFrames`. */
|
|
6902
|
-
subscriptionId: string(),
|
|
6903
|
-
/** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
|
|
6904
|
-
maxFps: number().nonnegative()
|
|
6905
|
-
});
|
|
6906
|
-
/**
|
|
6907
6834
|
* Wire schema for a decoded audio chunk (Phase 5 / D9). Mirrors the
|
|
6908
6835
|
* `DecodedAudioChunk` TS interface in `interfaces/stream-broker.ts`: PCM
|
|
6909
6836
|
* sample bytes plus the track parameters a consumer needs to interpret them.
|
|
@@ -6911,8 +6838,8 @@ var SubscribeFramesResultSchema = object({
|
|
|
6911
6838
|
* Audio chunks are tiny (a ~500ms AudioCodecSession window is a few KB of
|
|
6912
6839
|
* Float32 PCM), so unlike video frames they ship their bytes INLINE over
|
|
6913
6840
|
* tRPC / Moleculer — no shared-memory plane. `data` is typed `Uint8Array`
|
|
6914
|
-
* (the wire-serialisable supertype of `Buffer`)
|
|
6915
|
-
*
|
|
6841
|
+
* (the wire-serialisable supertype of `Buffer`); a `Buffer` is assignable to
|
|
6842
|
+
* it.
|
|
6916
6843
|
*/
|
|
6917
6844
|
var AudioChunkFormatSchema = _enum(AUDIO_CHUNK_FORMATS);
|
|
6918
6845
|
var DecodedAudioChunkSchema = object({
|
|
@@ -6930,11 +6857,10 @@ var DecodedAudioChunkSchema = object({
|
|
|
6930
6857
|
format: AudioChunkFormatSchema.optional()
|
|
6931
6858
|
});
|
|
6932
6859
|
/**
|
|
6933
|
-
* Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9).
|
|
6934
|
-
*
|
|
6935
|
-
*
|
|
6936
|
-
*
|
|
6937
|
-
* `pullAudioChunks`.
|
|
6860
|
+
* Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9). Audio ships
|
|
6861
|
+
* its bytes inline: a consumer asks the broker for the decoded audio-chunk
|
|
6862
|
+
* stream of one broker; the broker keeps a per-subscription bounded FIFO queue
|
|
6863
|
+
* the consumer drains via `pullAudioChunks`.
|
|
6938
6864
|
*/
|
|
6939
6865
|
var SubscribeAudioChunksInputSchema = object({
|
|
6940
6866
|
brokerId: string(),
|
|
@@ -6965,9 +6891,7 @@ var BrokerStatsSchema = object({
|
|
|
6965
6891
|
"stopped"
|
|
6966
6892
|
]),
|
|
6967
6893
|
inputFps: number(),
|
|
6968
|
-
decodeFps: number(),
|
|
6969
6894
|
encodedSubscribers: number(),
|
|
6970
|
-
decodedSubscribers: number(),
|
|
6971
6895
|
uptimeMs: number(),
|
|
6972
6896
|
bitrateKbps: number(),
|
|
6973
6897
|
idrIntervalMs: number(),
|
|
@@ -6980,14 +6904,6 @@ var BrokerStatsSchema = object({
|
|
|
6980
6904
|
preBufferMs: number(),
|
|
6981
6905
|
preBufferPackets: number(),
|
|
6982
6906
|
/**
|
|
6983
|
-
* Moleculer node id of the decoder provider currently servicing this
|
|
6984
|
-
* stream's decoded subscribers. `null` until the deferred decoder is
|
|
6985
|
-
* created (no decoded clients yet, or codec not detected). Surfaces the
|
|
6986
|
-
* runtime decoder placement so the UI can show "Decoder: <agent>" without
|
|
6987
|
-
* a separate cap call per broker.
|
|
6988
|
-
*/
|
|
6989
|
-
decoderNodeId: string().nullable(),
|
|
6990
|
-
/**
|
|
6991
6907
|
* Detected audio track parameters from the RTSP DESCRIBE / SDP. `null`
|
|
6992
6908
|
* when the stream has no audio track or the broker is in cold start.
|
|
6993
6909
|
* `supported = false` means the codec was detected but the local
|
|
@@ -11325,70 +11241,6 @@ var StorageLocationDeclarationSchema = object({
|
|
|
11325
11241
|
"backup"
|
|
11326
11242
|
]).optional()
|
|
11327
11243
|
});
|
|
11328
|
-
var DecoderStatsSchema = object({
|
|
11329
|
-
inputFps: number(),
|
|
11330
|
-
outputFps: number(),
|
|
11331
|
-
avgDecodeTimeMs: number(),
|
|
11332
|
-
droppedFrames: number(),
|
|
11333
|
-
/**
|
|
11334
|
-
* Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
|
|
11335
|
-
* lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
|
|
11336
|
-
* the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
|
|
11337
|
-
* is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
|
|
11338
|
-
*/
|
|
11339
|
-
lagMs: number().optional(),
|
|
11340
|
-
effectiveFps: number().optional(),
|
|
11341
|
-
adaptiveFps: number().optional()
|
|
11342
|
-
});
|
|
11343
|
-
var DecoderSessionConfigSchema = object({
|
|
11344
|
-
codec: string(),
|
|
11345
|
-
maxFps: number().default(0),
|
|
11346
|
-
outputFormat: _enum([
|
|
11347
|
-
"jpeg",
|
|
11348
|
-
"rgb",
|
|
11349
|
-
"bgr",
|
|
11350
|
-
"yuv420",
|
|
11351
|
-
"gray"
|
|
11352
|
-
]).default("jpeg"),
|
|
11353
|
-
scale: number().default(1),
|
|
11354
|
-
width: number().optional(),
|
|
11355
|
-
height: number().optional(),
|
|
11356
|
-
/**
|
|
11357
|
-
* Identifier of the camera this decoder session serves. Optional
|
|
11358
|
-
* because the cap is generic (any caller could request decode), but
|
|
11359
|
-
* stream-broker passes it so decoder logs include `deviceId` for
|
|
11360
|
-
* per-camera filtering when diagnosing failures (e.g. node-av
|
|
11361
|
-
* sendPacket errors on a single hung camera).
|
|
11362
|
-
*/
|
|
11363
|
-
deviceId: number().int().nonnegative().optional(),
|
|
11364
|
-
/**
|
|
11365
|
-
* Free-form tag for log scoping. Stream-broker uses
|
|
11366
|
-
* `broker:<deviceId>/<profile>`. Decoder session logger surfaces it
|
|
11367
|
-
* on every line so `grep tag=broker:5/high` filters one camera
|
|
11368
|
-
* profile cleanly.
|
|
11369
|
-
*/
|
|
11370
|
-
tag: string().optional(),
|
|
11371
|
-
/**
|
|
11372
|
-
* Where the session delivers decoded frames (Phase 5 / D9):
|
|
11373
|
-
*
|
|
11374
|
-
* - `'callback'` (default) — the legacy pixel path: decoded frames are
|
|
11375
|
-
* buffered as `DecodedFrame`s and drained via `pullFrames`.
|
|
11376
|
-
* - `'shm'` — the shared-memory frame plane: decoded frames are written
|
|
11377
|
-
* into an OS shared-memory ring and drained as zero-pixel
|
|
11378
|
-
* `FrameHandle`s via `pullHandles`. A session is one mode or the
|
|
11379
|
-
* other — `pullFrames` returns nothing for an `'shm'` session and
|
|
11380
|
-
* `pullHandles` returns nothing for a `'callback'` session.
|
|
11381
|
-
*/
|
|
11382
|
-
frameSink: _enum(["callback", "shm"]).default("callback"),
|
|
11383
|
-
/**
|
|
11384
|
-
* Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
|
|
11385
|
-
* a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
|
|
11386
|
-
* real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
|
|
11387
|
-
* stream-broker's `streamingDebug` gate — off by default so production logs
|
|
11388
|
-
* stay quiet and the emit path pays zero per-frame cost when disabled.
|
|
11389
|
-
*/
|
|
11390
|
-
debug: boolean().optional()
|
|
11391
|
-
});
|
|
11392
11244
|
/**
|
|
11393
11245
|
* Per-component log CHANNELS — the gate a hot path consults, and the registry
|
|
11394
11246
|
* an addon declares its channels in.
|
|
@@ -13592,13 +13444,6 @@ var BrokerRtspClientSchema = object({
|
|
|
13592
13444
|
lastRtpAt: number(),
|
|
13593
13445
|
bytesSent: number()
|
|
13594
13446
|
});
|
|
13595
|
-
var BrokerDecodedClientSchema = object({
|
|
13596
|
-
tag: string(),
|
|
13597
|
-
subscribedAt: number(),
|
|
13598
|
-
maxFps: number(),
|
|
13599
|
-
framesDelivered: number(),
|
|
13600
|
-
framesDropped: number()
|
|
13601
|
-
});
|
|
13602
13447
|
var BrokerAudioClientSchema = object({
|
|
13603
13448
|
tag: string(),
|
|
13604
13449
|
subscribedAt: number(),
|
|
@@ -13690,7 +13535,6 @@ var BrokerEncodedClientSchema = object({
|
|
|
13690
13535
|
});
|
|
13691
13536
|
var BrokerClientsSchema = object({
|
|
13692
13537
|
rtsp: array(BrokerRtspClientSchema).readonly(),
|
|
13693
|
-
decoded: array(BrokerDecodedClientSchema).readonly(),
|
|
13694
13538
|
audio: array(BrokerAudioClientSchema).readonly(),
|
|
13695
13539
|
encoded: array(BrokerEncodedClientSchema).readonly(),
|
|
13696
13540
|
pipeClients: number(),
|
|
@@ -14059,11 +13903,7 @@ method(object({
|
|
|
14059
13903
|
auth: "admin"
|
|
14060
13904
|
}), method(object({ brokerId: string() }), BrokerClientsSchema), method(object({
|
|
14061
13905
|
brokerId: string(),
|
|
14062
|
-
channel: _enum([
|
|
14063
|
-
"rtsp",
|
|
14064
|
-
"decoded",
|
|
14065
|
-
"audio"
|
|
14066
|
-
]),
|
|
13906
|
+
channel: _enum(["rtsp", "audio"]),
|
|
14067
13907
|
handle: string()
|
|
14068
13908
|
}), object({ killed: boolean() }), {
|
|
14069
13909
|
kind: "mutation",
|
|
@@ -14098,10 +13938,7 @@ method(object({
|
|
|
14098
13938
|
}), method(SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, { kind: "mutation" }), method(object({
|
|
14099
13939
|
subscriptionId: string(),
|
|
14100
13940
|
maxCount: number().int().positive().default(8)
|
|
14101
|
-
}), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(
|
|
14102
|
-
subscriptionId: string(),
|
|
14103
|
-
maxCount: number().int().positive().default(4)
|
|
14104
|
-
}), array(FrameHandleSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
|
|
13941
|
+
}), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
|
|
14105
13942
|
brokerId: string(),
|
|
14106
13943
|
seconds: number().min(0).max(30)
|
|
14107
13944
|
}), _void(), {
|
|
@@ -15258,54 +15095,12 @@ id: union([string(), number()]) }), {
|
|
|
15258
15095
|
kind: "mutation",
|
|
15259
15096
|
auth: "admin"
|
|
15260
15097
|
});
|
|
15261
|
-
|
|
15262
|
-
* shm ring usage stats for a `frameSink: 'shm'` decoder session —
|
|
15263
|
-
* exposed via `decoder.getShmStats` so downstream consumers can
|
|
15264
|
-
* observe ring pressure (slot count, byte budget, hit/miss ratio).
|
|
15265
|
-
*/
|
|
15266
|
-
var ShmRingStatsSchema = object({
|
|
15267
|
-
sessionId: string(),
|
|
15268
|
-
slotCount: number().int(),
|
|
15269
|
-
slotByteLength: number().int(),
|
|
15270
|
-
segmentBytes: number().int(),
|
|
15271
|
-
budgetMb: number().int(),
|
|
15272
|
-
framesWritten: number().int(),
|
|
15273
|
-
getFrameHits: number().int(),
|
|
15274
|
-
getFrameMisses: number().int()
|
|
15275
|
-
});
|
|
15276
|
-
method(object({ codec: string() }), boolean()), method(_void(), object({
|
|
15098
|
+
method(_void(), object({
|
|
15277
15099
|
id: string(),
|
|
15278
15100
|
name: string(),
|
|
15279
|
-
isPullMode: boolean().optional(),
|
|
15280
|
-
priority: number().optional(),
|
|
15281
15101
|
hwaccel: string().optional(),
|
|
15282
15102
|
probedBestHwaccel: string().optional()
|
|
15283
|
-
})), method(
|
|
15284
|
-
sessionId: string(),
|
|
15285
|
-
nodeId: string()
|
|
15286
|
-
})), method(object({ sessionId: string() }), _void()), method(object({
|
|
15287
|
-
sessionId: string(),
|
|
15288
|
-
packet: EncodedPacketSchema
|
|
15289
|
-
}), _void()), method(object({
|
|
15290
|
-
sessionId: string(),
|
|
15291
|
-
url: string()
|
|
15292
|
-
}), _void()), method(object({
|
|
15293
|
-
sessionId: string(),
|
|
15294
|
-
maxCount: number().default(1),
|
|
15295
|
-
waitMs: number().optional()
|
|
15296
|
-
}), array(DecodedFrameSchema)), method(object({
|
|
15297
|
-
sessionId: string(),
|
|
15298
|
-
maxCount: number().default(1),
|
|
15299
|
-
waitMs: number().optional()
|
|
15300
|
-
}), array(FrameHandleSchema)), method(object({ handle: FrameHandleSchema }), DecodedFrameSchema.nullable()), method(object({ sessionId: string() }), ShmRingStatsSchema.nullable()), method(object({
|
|
15301
|
-
sessionId: string(),
|
|
15302
|
-
config: DecoderSessionConfigSchema.partial()
|
|
15303
|
-
}), _void()), method(object({ sessionId: string() }), DecoderStatsSchema), method(_void(), array(object({
|
|
15304
|
-
sessionId: string(),
|
|
15305
|
-
codec: string(),
|
|
15306
|
-
outputFormat: string(),
|
|
15307
|
-
createdAtMs: number()
|
|
15308
|
-
})).readonly()), method(_void(), object({ backend: string() }), {
|
|
15103
|
+
})), method(_void(), object({ backend: string() }), {
|
|
15309
15104
|
kind: "mutation",
|
|
15310
15105
|
auth: "admin"
|
|
15311
15106
|
});
|
|
@@ -22375,8 +22170,8 @@ function interpretStoredClusterModel(raw) {
|
|
|
22375
22170
|
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
22376
22171
|
stepId: "face-embedding",
|
|
22377
22172
|
key: "minLandmarkFaceSize",
|
|
22378
|
-
label: "Min face size
|
|
22379
|
-
description: "
|
|
22173
|
+
label: "Min face size to embed (detection-frame px)",
|
|
22174
|
+
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.",
|
|
22380
22175
|
type: "slider",
|
|
22381
22176
|
min: 0,
|
|
22382
22177
|
max: 64,
|
|
@@ -26508,14 +26303,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
26508
26303
|
* Per-inference-device live load (multi-device C4). One entry per deviceKey
|
|
26509
26304
|
* this runner currently has attached cameras on, so the orchestrator's second
|
|
26510
26305
|
* `balance()` pass (over a node's devices) weights on real per-pool session
|
|
26511
|
-
* counts. Empty on single-device / pre-multi-device runners.
|
|
26512
|
-
* per
|
|
26306
|
+
* counts. Empty on single-device / pre-multi-device runners. There is no
|
|
26307
|
+
* per-device queue depth: the inference pool's backlog has no accessor, and
|
|
26308
|
+
* a field that always read 0 was removed rather than shown as a measurement
|
|
26309
|
+
* (D762).
|
|
26513
26310
|
*/
|
|
26514
26311
|
devices: array(object({
|
|
26515
26312
|
deviceKey: string(),
|
|
26516
26313
|
backend: string(),
|
|
26517
|
-
attachedCameras: number()
|
|
26518
|
-
queueDepthTotal: number()
|
|
26314
|
+
attachedCameras: number()
|
|
26519
26315
|
})).default([]),
|
|
26520
26316
|
/** Hardware capability flags reported by this node. */
|
|
26521
26317
|
hardware: object({
|
|
@@ -26838,7 +26634,10 @@ var PipelineAssignmentSchema = object({
|
|
|
26838
26634
|
});
|
|
26839
26635
|
/**
|
|
26840
26636
|
* Per-agent load summary surfaced to the load balancer + dashboards.
|
|
26841
|
-
* Aggregated from each runner's `getLocalLoad` cap call.
|
|
26637
|
+
* Aggregated from each runner's `getLocalLoad` cap call. In the
|
|
26638
|
+
* `getAgentLoad` report, a single-device node's default-pool sessions (no
|
|
26639
|
+
* `deviceKey`) are credited to its one eligible device in `load.devices` —
|
|
26640
|
+
* the default pool IS that device (D745); the balancer's census stays raw.
|
|
26842
26641
|
*/
|
|
26843
26642
|
var AgentLoadSummarySchema = object({
|
|
26844
26643
|
nodeId: string(),
|
|
@@ -26927,8 +26726,14 @@ var CameraBrokerStatusSchema = object({
|
|
|
26927
26726
|
width: number(),
|
|
26928
26727
|
height: number(),
|
|
26929
26728
|
subscribers: number(),
|
|
26930
|
-
|
|
26931
|
-
|
|
26729
|
+
/**
|
|
26730
|
+
* Encoded packets/s the broker receives from the camera. null when the
|
|
26731
|
+
* broker's stats read failed — unknown, never 0 (a 0 here reads as a stall).
|
|
26732
|
+
* There is no output rate: decoding runs in the session decode workers, not
|
|
26733
|
+
* in the broker, so the broker's own decoded-frame rate is 0 on every live
|
|
26734
|
+
* camera and is not served (D758).
|
|
26735
|
+
*/
|
|
26736
|
+
inFps: number().nullable()
|
|
26932
26737
|
})).readonly(),
|
|
26933
26738
|
webrtcSessions: number(),
|
|
26934
26739
|
rtspRestream: boolean()
|
|
@@ -30017,8 +29822,6 @@ var WebrtcStreamChoiceSchema = object({
|
|
|
30017
29822
|
]).nullable(),
|
|
30018
29823
|
/** Input FPS from the camera (null for adaptive). */
|
|
30019
29824
|
inputFps: number().nullable(),
|
|
30020
|
-
/** Decoded FPS (null for adaptive). */
|
|
30021
|
-
decodeFps: number().nullable(),
|
|
30022
29825
|
/** Bitrate in kbps (null for adaptive). */
|
|
30023
29826
|
bitrateKbps: number().nullable()
|
|
30024
29827
|
});
|
|
@@ -40264,90 +40067,18 @@ Object.freeze({
|
|
|
40264
40067
|
addonId: null,
|
|
40265
40068
|
access: "create"
|
|
40266
40069
|
},
|
|
40267
|
-
"decoder.createSession": {
|
|
40268
|
-
capName: "decoder",
|
|
40269
|
-
capScope: "system",
|
|
40270
|
-
addonId: null,
|
|
40271
|
-
access: "view"
|
|
40272
|
-
},
|
|
40273
|
-
"decoder.destroySession": {
|
|
40274
|
-
capName: "decoder",
|
|
40275
|
-
capScope: "system",
|
|
40276
|
-
addonId: null,
|
|
40277
|
-
access: "delete"
|
|
40278
|
-
},
|
|
40279
|
-
"decoder.getFrame": {
|
|
40280
|
-
capName: "decoder",
|
|
40281
|
-
capScope: "system",
|
|
40282
|
-
addonId: null,
|
|
40283
|
-
access: "view"
|
|
40284
|
-
},
|
|
40285
40070
|
"decoder.getInfo": {
|
|
40286
40071
|
capName: "decoder",
|
|
40287
40072
|
capScope: "system",
|
|
40288
40073
|
addonId: null,
|
|
40289
40074
|
access: "view"
|
|
40290
40075
|
},
|
|
40291
|
-
"decoder.getShmStats": {
|
|
40292
|
-
capName: "decoder",
|
|
40293
|
-
capScope: "system",
|
|
40294
|
-
addonId: null,
|
|
40295
|
-
access: "view"
|
|
40296
|
-
},
|
|
40297
|
-
"decoder.getStats": {
|
|
40298
|
-
capName: "decoder",
|
|
40299
|
-
capScope: "system",
|
|
40300
|
-
addonId: null,
|
|
40301
|
-
access: "view"
|
|
40302
|
-
},
|
|
40303
|
-
"decoder.listActiveSessions": {
|
|
40304
|
-
capName: "decoder",
|
|
40305
|
-
capScope: "system",
|
|
40306
|
-
addonId: null,
|
|
40307
|
-
access: "view"
|
|
40308
|
-
},
|
|
40309
|
-
"decoder.openStream": {
|
|
40310
|
-
capName: "decoder",
|
|
40311
|
-
capScope: "system",
|
|
40312
|
-
addonId: null,
|
|
40313
|
-
access: "view"
|
|
40314
|
-
},
|
|
40315
|
-
"decoder.pullFrames": {
|
|
40316
|
-
capName: "decoder",
|
|
40317
|
-
capScope: "system",
|
|
40318
|
-
addonId: null,
|
|
40319
|
-
access: "view"
|
|
40320
|
-
},
|
|
40321
|
-
"decoder.pullHandles": {
|
|
40322
|
-
capName: "decoder",
|
|
40323
|
-
capScope: "system",
|
|
40324
|
-
addonId: null,
|
|
40325
|
-
access: "view"
|
|
40326
|
-
},
|
|
40327
|
-
"decoder.pushPacket": {
|
|
40328
|
-
capName: "decoder",
|
|
40329
|
-
capScope: "system",
|
|
40330
|
-
addonId: null,
|
|
40331
|
-
access: "view"
|
|
40332
|
-
},
|
|
40333
40076
|
"decoder.reprobeHwaccel": {
|
|
40334
40077
|
capName: "decoder",
|
|
40335
40078
|
capScope: "system",
|
|
40336
40079
|
addonId: null,
|
|
40337
40080
|
access: "create"
|
|
40338
40081
|
},
|
|
40339
|
-
"decoder.supportsCodec": {
|
|
40340
|
-
capName: "decoder",
|
|
40341
|
-
capScope: "system",
|
|
40342
|
-
addonId: null,
|
|
40343
|
-
access: "view"
|
|
40344
|
-
},
|
|
40345
|
-
"decoder.updateConfig": {
|
|
40346
|
-
capName: "decoder",
|
|
40347
|
-
capScope: "system",
|
|
40348
|
-
addonId: null,
|
|
40349
|
-
access: "view"
|
|
40350
|
-
},
|
|
40351
40082
|
"detectionPipeline.applyDeviceSettingsPatch": {
|
|
40352
40083
|
capName: "detection-pipeline",
|
|
40353
40084
|
capScope: "device",
|
|
@@ -45394,12 +45125,6 @@ Object.freeze({
|
|
|
45394
45125
|
addonId: null,
|
|
45395
45126
|
access: "view"
|
|
45396
45127
|
},
|
|
45397
|
-
"streamBroker.pullFrameHandles": {
|
|
45398
|
-
capName: "stream-broker",
|
|
45399
|
-
capScope: "system",
|
|
45400
|
-
addonId: null,
|
|
45401
|
-
access: "view"
|
|
45402
|
-
},
|
|
45403
45128
|
"streamBroker.regenerateRtspToken": {
|
|
45404
45129
|
capName: "stream-broker",
|
|
45405
45130
|
capScope: "system",
|
|
@@ -45466,12 +45191,6 @@ Object.freeze({
|
|
|
45466
45191
|
addonId: null,
|
|
45467
45192
|
access: "create"
|
|
45468
45193
|
},
|
|
45469
|
-
"streamBroker.subscribeFrames": {
|
|
45470
|
-
capName: "stream-broker",
|
|
45471
|
-
capScope: "system",
|
|
45472
|
-
addonId: null,
|
|
45473
|
-
access: "create"
|
|
45474
|
-
},
|
|
45475
45194
|
"streamBroker.unassignProfile": {
|
|
45476
45195
|
capName: "stream-broker",
|
|
45477
45196
|
capScope: "system",
|
|
@@ -45484,12 +45203,6 @@ Object.freeze({
|
|
|
45484
45203
|
addonId: null,
|
|
45485
45204
|
access: "create"
|
|
45486
45205
|
},
|
|
45487
|
-
"streamBroker.unsubscribeFrames": {
|
|
45488
|
-
capName: "stream-broker",
|
|
45489
|
-
capScope: "system",
|
|
45490
|
-
addonId: null,
|
|
45491
|
-
access: "create"
|
|
45492
|
-
},
|
|
45493
45206
|
"streamCatalog.getCatalog": {
|
|
45494
45207
|
capName: "stream-catalog",
|
|
45495
45208
|
capScope: "device",
|
|
@@ -48031,11 +47744,6 @@ Object.freeze({
|
|
|
48031
47744
|
form: "single",
|
|
48032
47745
|
optional: false
|
|
48033
47746
|
}],
|
|
48034
|
-
"decoder.createSession": [{
|
|
48035
|
-
name: "deviceId",
|
|
48036
|
-
form: "single",
|
|
48037
|
-
optional: true
|
|
48038
|
-
}],
|
|
48039
47747
|
"detectionPipeline.applyDeviceSettingsPatch": [{
|
|
48040
47748
|
name: "deviceId",
|
|
48041
47749
|
form: "single",
|
|
@@ -54752,6 +54460,40 @@ var LoadShedController = class LoadShedController {
|
|
|
54752
54460
|
}
|
|
54753
54461
|
};
|
|
54754
54462
|
//#endregion
|
|
54463
|
+
//#region src/default-pool-attribution.ts
|
|
54464
|
+
/** The backend prefix of a `<backend>:<device>` key (bare `cpu` → `cpu`). */
|
|
54465
|
+
function backendOf(deviceKey) {
|
|
54466
|
+
const colon = deviceKey.indexOf(":");
|
|
54467
|
+
return colon >= 0 ? deviceKey.slice(0, colon) : deviceKey;
|
|
54468
|
+
}
|
|
54469
|
+
/**
|
|
54470
|
+
* `load` with its unattributed sessions credited to `eligibleKeys[0]` when that
|
|
54471
|
+
* is the node's ONLY eligible device; `load` itself (same reference) otherwise.
|
|
54472
|
+
* `eligibleKeys` null = the eligible set is not known.
|
|
54473
|
+
*/
|
|
54474
|
+
function attributeDefaultPoolSessions(load, eligibleKeys) {
|
|
54475
|
+
if (eligibleKeys === null || eligibleKeys.length !== 1) return load;
|
|
54476
|
+
const onlyKey = eligibleKeys[0];
|
|
54477
|
+
if (onlyKey === void 0) return load;
|
|
54478
|
+
const attributed = load.devices.reduce((sum, d) => sum + d.attachedCameras, 0);
|
|
54479
|
+
const unattributed = load.attachedCameras - attributed;
|
|
54480
|
+
if (unattributed <= 0) return load;
|
|
54481
|
+
const existing = load.devices.find((d) => d.deviceKey === onlyKey);
|
|
54482
|
+
const credited = existing ? {
|
|
54483
|
+
...existing,
|
|
54484
|
+
attachedCameras: existing.attachedCameras + unattributed
|
|
54485
|
+
} : {
|
|
54486
|
+
deviceKey: onlyKey,
|
|
54487
|
+
backend: backendOf(onlyKey),
|
|
54488
|
+
attachedCameras: unattributed
|
|
54489
|
+
};
|
|
54490
|
+
const devices = [...load.devices.filter((d) => d.deviceKey !== onlyKey), credited].toSorted((a, b) => a.deviceKey.localeCompare(b.deviceKey));
|
|
54491
|
+
return {
|
|
54492
|
+
...load,
|
|
54493
|
+
devices
|
|
54494
|
+
};
|
|
54495
|
+
}
|
|
54496
|
+
//#endregion
|
|
54755
54497
|
//#region src/dispatch-timing.ts
|
|
54756
54498
|
/**
|
|
54757
54499
|
* How long the placement census waits for ONE runner's `getLocalCameras`
|
|
@@ -54818,6 +54560,25 @@ var AgentLoadService = class AgentLoadService {
|
|
|
54818
54560
|
getAgentLoadSummaries() {
|
|
54819
54561
|
return [...this.cachedAgentLoad.values()];
|
|
54820
54562
|
}
|
|
54563
|
+
/**
|
|
54564
|
+
* The cached summaries as the load REPORT (`getAgentLoad`) carries them: a
|
|
54565
|
+
* single-device node's default-pool sessions credited to its one device
|
|
54566
|
+
* (`default-pool-attribution.ts`). The balancer's census
|
|
54567
|
+
* ({@link collectAgentLoad}) stays the runner's raw answer.
|
|
54568
|
+
*/
|
|
54569
|
+
async reportedAgentLoad() {
|
|
54570
|
+
const resolve = this.deps.eligibleDeviceKeys;
|
|
54571
|
+
const summaries = this.getAgentLoadSummaries();
|
|
54572
|
+
if (resolve === void 0) return summaries;
|
|
54573
|
+
return Promise.all(summaries.map(async (summary) => {
|
|
54574
|
+
const eligible = await resolve(summary.nodeId).catch(() => null);
|
|
54575
|
+
const load = attributeDefaultPoolSessions(summary.load, eligible);
|
|
54576
|
+
return load === summary.load ? summary : {
|
|
54577
|
+
...summary,
|
|
54578
|
+
load
|
|
54579
|
+
};
|
|
54580
|
+
}));
|
|
54581
|
+
}
|
|
54821
54582
|
cachedAgentLoadNodeIds() {
|
|
54822
54583
|
return [...this.cachedAgentLoad.keys()];
|
|
54823
54584
|
}
|
|
@@ -57265,8 +57026,7 @@ function mapBroker(brokerResult) {
|
|
|
57265
57026
|
width: p.width,
|
|
57266
57027
|
height: p.height,
|
|
57267
57028
|
subscribers: p.subscribers,
|
|
57268
|
-
inFps: p.inFps
|
|
57269
|
-
outFps: p.outFps
|
|
57029
|
+
inFps: p.inFps
|
|
57270
57030
|
})),
|
|
57271
57031
|
webrtcSessions: brokerResult.webrtcSessions,
|
|
57272
57032
|
rtspRestream: brokerResult.rtspRestream
|
|
@@ -57653,11 +57413,9 @@ var CameraStatusService = class {
|
|
|
57653
57413
|
* `allSlotsFetch` (fetched once by the caller) to avoid a second
|
|
57654
57414
|
* round-trip. Per-slot `getBrokerStats` + `listClients` are fetched in
|
|
57655
57415
|
* parallel. WebRTC sessions are counted by filtering `encoded[]` entries
|
|
57656
|
-
* whose `attribution.kind` is one of the `WEBRTC_KINDS`.
|
|
57657
|
-
* broker's actual decode-session node into `liveDecoder` (T6) — the first
|
|
57658
|
-
* slot that reports one wins.
|
|
57416
|
+
* whose `attribution.kind` is one of the `WEBRTC_KINDS`.
|
|
57659
57417
|
*/
|
|
57660
|
-
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57418
|
+
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, sink) {
|
|
57661
57419
|
if (!api || !allSlotsFetch) return Promise.resolve(null);
|
|
57662
57420
|
return this.boundedStage(allSlotsFetch.then(async (slots) => {
|
|
57663
57421
|
const deviceSlots = slots.filter((s) => s.deviceId === deviceId);
|
|
@@ -57674,19 +57432,16 @@ var CameraStatusService = class {
|
|
|
57674
57432
|
clients
|
|
57675
57433
|
};
|
|
57676
57434
|
})), pass.rtspEntries(api, sourceNodeId).catch(() => null)]);
|
|
57677
|
-
const profileDetails = statsAndClients.map(({ slot, stats, clients }) => ({
|
|
57678
|
-
profile: slot.profile,
|
|
57679
|
-
status: slot.status,
|
|
57680
|
-
codec: stats?.codec ?? slot.codec ?? "",
|
|
57681
|
-
width: slot.resolution?.width ?? 0,
|
|
57682
|
-
height: slot.resolution?.height ?? 0,
|
|
57683
|
-
subscribers: clients?.encodedSubscribers ?? 0,
|
|
57684
|
-
inFps: stats?.inputFps ?? 0,
|
|
57685
|
-
outFps: stats?.decodeFps ?? 0
|
|
57686
|
-
}));
|
|
57687
|
-
for (const { stats } of statsAndClients) if (liveDecoder.nodeId === null && typeof stats?.decoderNodeId === "string") liveDecoder.nodeId = stats.decoderNodeId;
|
|
57688
57435
|
return {
|
|
57689
|
-
profiles:
|
|
57436
|
+
profiles: statsAndClients.map(({ slot, stats, clients }) => ({
|
|
57437
|
+
profile: slot.profile,
|
|
57438
|
+
status: slot.status,
|
|
57439
|
+
codec: stats?.codec ?? slot.codec ?? "",
|
|
57440
|
+
width: slot.resolution?.width ?? 0,
|
|
57441
|
+
height: slot.resolution?.height ?? 0,
|
|
57442
|
+
subscribers: clients?.encodedSubscribers ?? 0,
|
|
57443
|
+
inFps: stats?.inputFps ?? null
|
|
57444
|
+
})),
|
|
57690
57445
|
webrtcSessions: statsAndClients.reduce((total, { clients }) => {
|
|
57691
57446
|
if (!clients) return total;
|
|
57692
57447
|
return total + clients.encoded.filter((c) => WEBRTC_KINDS.has(c.attribution.kind)).length;
|
|
@@ -57880,10 +57635,9 @@ var CameraStatusService = class {
|
|
|
57880
57635
|
const api = this.deps.api();
|
|
57881
57636
|
const degradations = { entries: [] };
|
|
57882
57637
|
const { detectionNodeId, sourceNodeId, pinned, detectionReason, audioNodeId, audioPinned } = this.buildAssignmentContext(deviceId);
|
|
57883
|
-
const liveDecoder = { nodeId: null };
|
|
57884
57638
|
const allSlotsFetch = api ? pass.profileSlots(api, sourceNodeId) : null;
|
|
57885
57639
|
const sourceFetch = this.buildSourceStage(api, allSlotsFetch, deviceId, degradations);
|
|
57886
|
-
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57640
|
+
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, degradations);
|
|
57887
57641
|
const decoderFetch = this.buildDecoderStage(detectionNodeId);
|
|
57888
57642
|
const motionResult = this.buildMotionStage(deviceId);
|
|
57889
57643
|
const detectionFetch = this.buildDetectionStage(api, detectionNodeId, deviceId, pass, degradations);
|
|
@@ -57898,11 +57652,10 @@ var CameraStatusService = class {
|
|
|
57898
57652
|
switchesFetch
|
|
57899
57653
|
]);
|
|
57900
57654
|
const audioResult = this.buildAudioStage(audioNodeId, switchedOff);
|
|
57901
|
-
const
|
|
57902
|
-
const decoderNodeId = liveDecoderNodeId ?? detectionNodeId;
|
|
57655
|
+
const decoderNodeId = detectionNodeId;
|
|
57903
57656
|
const reasons = {
|
|
57904
57657
|
detection: detectionReason,
|
|
57905
|
-
decoder:
|
|
57658
|
+
decoder: decoderNodeId !== null ? "co-located" : void 0,
|
|
57906
57659
|
audio: audioPinned ? "manual" : void 0
|
|
57907
57660
|
};
|
|
57908
57661
|
return composeCameraStatus({
|
|
@@ -60139,7 +59892,7 @@ function deviceAsLoad(deviceKey, load) {
|
|
|
60139
59892
|
activeCameras: 0,
|
|
60140
59893
|
avgInferenceFps: 0,
|
|
60141
59894
|
avgInferenceTimeMs: 0,
|
|
60142
|
-
queueDepthTotal:
|
|
59895
|
+
queueDepthTotal: 0,
|
|
60143
59896
|
devices: [],
|
|
60144
59897
|
hardware: { hasGpu: false }
|
|
60145
59898
|
};
|
|
@@ -61119,8 +60872,7 @@ function tallyLoad(load, nodeDelta, perDevice) {
|
|
|
61119
60872
|
}), ...[...perDevice ?? /* @__PURE__ */ new Map()].filter(([deviceKey, delta]) => !known.has(deviceKey) && delta > 0).map(([deviceKey, delta]) => ({
|
|
61120
60873
|
deviceKey,
|
|
61121
60874
|
backend: deviceKey.split(":")[0] ?? deviceKey,
|
|
61122
|
-
attachedCameras: delta
|
|
61123
|
-
queueDepthTotal: 0
|
|
60875
|
+
attachedCameras: delta
|
|
61124
60876
|
}))];
|
|
61125
60877
|
return {
|
|
61126
60878
|
...load,
|
|
@@ -69108,6 +68860,10 @@ async function buildOrchestratorControllers(deps) {
|
|
|
69108
68860
|
onCensus: (entries) => {
|
|
69109
68861
|
motionSliceGate?.noteCensus(entries);
|
|
69110
68862
|
providerSliceGate?.refreshIfStale("runner-census");
|
|
68863
|
+
},
|
|
68864
|
+
eligibleDeviceKeys: async (nodeId) => {
|
|
68865
|
+
const read = await deps.getEligibleInferenceDevicesIfCached(nodeId);
|
|
68866
|
+
return read.kind === "eligible" ? Object.keys(read.eligible) : null;
|
|
69111
68867
|
}
|
|
69112
68868
|
});
|
|
69113
68869
|
/**
|
|
@@ -69966,12 +69722,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
69966
69722
|
id: CLUSTER_MODEL_SECTION_ID,
|
|
69967
69723
|
title: "Enrichment models",
|
|
69968
69724
|
tab: "pipeline",
|
|
69969
|
-
description: "The
|
|
69725
|
+
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.",
|
|
69970
69726
|
fields: [...CLUSTER_MODEL_SCOPED_STEPS.map((step) => ({
|
|
69971
69727
|
key: clusterModelSettingKey(step.stepId),
|
|
69972
69728
|
type: "select",
|
|
69973
69729
|
label: step.label,
|
|
69974
|
-
description: `
|
|
69730
|
+
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.`,
|
|
69975
69731
|
options: step.options.map((o) => ({
|
|
69976
69732
|
value: o.id,
|
|
69977
69733
|
label: o.label
|
|
@@ -69993,12 +69749,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
69993
69749
|
id: DETAIL_CROP_SECTION_ID,
|
|
69994
69750
|
title: "Enrichment crop",
|
|
69995
69751
|
tab: "pipeline",
|
|
69996
|
-
description: "How the crop
|
|
69752
|
+
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).",
|
|
69997
69753
|
fields: [{
|
|
69998
69754
|
key: DETAIL_CROP_PADDING_KEY,
|
|
69999
69755
|
type: "slider",
|
|
70000
69756
|
label: "Crop margin",
|
|
70001
|
-
description: "
|
|
69757
|
+
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.",
|
|
70002
69758
|
min: DETAIL_CROP_PADDING_FIELD.min,
|
|
70003
69759
|
max: DETAIL_CROP_PADDING_FIELD.max,
|
|
70004
69760
|
step: DETAIL_CROP_PADDING_FIELD.step,
|
|
@@ -70008,7 +69764,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70008
69764
|
key: DETAIL_CROP_SQUARE_KEY,
|
|
70009
69765
|
type: "boolean",
|
|
70010
69766
|
label: "Square the crop",
|
|
70011
|
-
description: "
|
|
69767
|
+
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.",
|
|
70012
69768
|
default: DEFAULT_DETAIL_CROP_CONVENTION.square
|
|
70013
69769
|
}]
|
|
70014
69770
|
},
|
|
@@ -70016,13 +69772,13 @@ function buildGlobalSettingsSections(options) {
|
|
|
70016
69772
|
id: NATIVE_LEASE_SECTION_ID,
|
|
70017
69773
|
title: "Native frame lease",
|
|
70018
69774
|
tab: "pipeline",
|
|
70019
|
-
description: "How
|
|
69775
|
+
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.",
|
|
70020
69776
|
fields: [
|
|
70021
69777
|
{
|
|
70022
69778
|
key: NATIVE_LEASE_HOLD_KEY,
|
|
70023
69779
|
type: "slider",
|
|
70024
69780
|
label: "Frames held at once",
|
|
70025
|
-
description: "
|
|
69781
|
+
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.",
|
|
70026
69782
|
min: NATIVE_LEASE_HOLD_FIELD.min,
|
|
70027
69783
|
max: NATIVE_LEASE_HOLD_FIELD.max,
|
|
70028
69784
|
step: NATIVE_LEASE_HOLD_FIELD.step,
|
|
@@ -70034,7 +69790,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70034
69790
|
key: NATIVE_LEASE_TILE_BUDGET_KEY,
|
|
70035
69791
|
type: "slider",
|
|
70036
69792
|
label: "Subject tile RAM",
|
|
70037
|
-
description: "RAM per
|
|
69793
|
+
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).",
|
|
70038
69794
|
min: NATIVE_LEASE_TILE_BUDGET_FIELD.min,
|
|
70039
69795
|
max: NATIVE_LEASE_TILE_BUDGET_FIELD.max,
|
|
70040
69796
|
step: NATIVE_LEASE_TILE_BUDGET_FIELD.step,
|
|
@@ -70046,7 +69802,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70046
69802
|
key: NATIVE_LEASE_SCENE_BUDGET_KEY,
|
|
70047
69803
|
type: "slider",
|
|
70048
69804
|
label: "Scene tile RAM",
|
|
70049
|
-
description: "RAM per
|
|
69805
|
+
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).",
|
|
70050
69806
|
min: NATIVE_LEASE_SCENE_BUDGET_FIELD.min,
|
|
70051
69807
|
max: NATIVE_LEASE_SCENE_BUDGET_FIELD.max,
|
|
70052
69808
|
step: NATIVE_LEASE_SCENE_BUDGET_FIELD.step,
|
|
@@ -70058,7 +69814,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70058
69814
|
key: NATIVE_LEASE_BUDGET_KEY,
|
|
70059
69815
|
type: "slider",
|
|
70060
69816
|
label: "Lease RAM ceiling",
|
|
70061
|
-
description: "
|
|
69817
|
+
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.",
|
|
70062
69818
|
min: NATIVE_LEASE_BUDGET_FIELD.min,
|
|
70063
69819
|
max: NATIVE_LEASE_BUDGET_FIELD.max,
|
|
70064
69820
|
step: NATIVE_LEASE_BUDGET_FIELD.step,
|
|
@@ -70070,7 +69826,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70070
69826
|
key: NATIVE_LEASE_ACTIVITY_KEY,
|
|
70071
69827
|
type: "slider",
|
|
70072
69828
|
label: "Demand window",
|
|
70073
|
-
description: "
|
|
69829
|
+
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).",
|
|
70074
69830
|
min: NATIVE_LEASE_ACTIVITY_FIELD.min,
|
|
70075
69831
|
max: NATIVE_LEASE_ACTIVITY_FIELD.max,
|
|
70076
69832
|
step: NATIVE_LEASE_ACTIVITY_FIELD.step,
|
|
@@ -70083,7 +69839,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70083
69839
|
key: NATIVE_LEASE_ADMISSION_KEY,
|
|
70084
69840
|
type: "select",
|
|
70085
69841
|
label: "What to retain",
|
|
70086
|
-
description: "
|
|
69842
|
+
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.",
|
|
70087
69843
|
options: NATIVE_LEASE_ADMISSION_FIELD.options,
|
|
70088
69844
|
default: NATIVE_LEASE_ADMISSION_FIELD.default
|
|
70089
69845
|
}
|
|
@@ -70096,7 +69852,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70096
69852
|
{
|
|
70097
69853
|
key: "onDisconnect",
|
|
70098
69854
|
type: "select",
|
|
70099
|
-
label: "
|
|
69855
|
+
label: "When a node disconnects",
|
|
69856
|
+
description: "Move its unpinned cameras to other nodes, or leave them stopped.",
|
|
70100
69857
|
default: DEFAULT_FAILOVER_POLICY.onDisconnect,
|
|
70101
69858
|
options: [{
|
|
70102
69859
|
value: "migrate",
|
|
@@ -70109,7 +69866,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70109
69866
|
{
|
|
70110
69867
|
key: "pinnedOnDisconnect",
|
|
70111
69868
|
type: "select",
|
|
70112
|
-
label: "
|
|
69869
|
+
label: "Its pinned cameras",
|
|
69870
|
+
description: "Keep the pin and wait for the node, or drop the pin and move them.",
|
|
70113
69871
|
default: DEFAULT_FAILOVER_POLICY.pinnedOnDisconnect,
|
|
70114
69872
|
options: [{
|
|
70115
69873
|
value: "leave-pinned",
|
|
@@ -70122,7 +69880,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70122
69880
|
{
|
|
70123
69881
|
key: "onReconnect",
|
|
70124
69882
|
type: "select",
|
|
70125
|
-
label: "
|
|
69883
|
+
label: "When it comes back",
|
|
69884
|
+
description: "Put its cameras back where they were, or rebalance the whole cluster.",
|
|
70126
69885
|
default: DEFAULT_FAILOVER_POLICY.onReconnect,
|
|
70127
69886
|
options: [{
|
|
70128
69887
|
value: "restore",
|
|
@@ -72123,7 +71882,7 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
72123
71882
|
async getAgentLoad() {
|
|
72124
71883
|
await this.loadService.refreshDecodeHwaccels();
|
|
72125
71884
|
await this.loadService.collectAgentLoad();
|
|
72126
|
-
return this.loadService.
|
|
71885
|
+
return this.loadService.reportedAgentLoad();
|
|
72127
71886
|
}
|
|
72128
71887
|
async getGlobalMetrics() {
|
|
72129
71888
|
const summaries = await this.getAgentLoad();
|