@camstack/addon-pipeline-orchestrator 1.2.295 → 1.2.297
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-BqsJU_pw.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-mnuctck6.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-BvAW3H5o.mjs +26 -0
- package/dist/{hostInit-B1qObv0b.mjs → hostInit-ButtQWCS.mjs} +3 -3
- package/dist/index.js +192 -370
- package/dist/index.mjs +192 -370
- 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
|
});
|
|
@@ -30569,6 +30372,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
|
|
|
30569
30372
|
var RestartAddonResultSchema = unknown();
|
|
30570
30373
|
var InstallPackageResultSchema = unknown();
|
|
30571
30374
|
var ReloadPackagesResultSchema = unknown();
|
|
30375
|
+
/**
|
|
30376
|
+
* What an uninstall did on ONE node.
|
|
30377
|
+
* - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
|
|
30378
|
+
* - `not-installed` — the node did not have it (nothing to do).
|
|
30379
|
+
* - `refused` — protected / bootstrap package; nothing touched.
|
|
30380
|
+
* - `failed` — attempted and did not complete; `error` says why.
|
|
30381
|
+
* - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
|
|
30382
|
+
* back-fill never returns the package, and the stale-addon sweep removes the
|
|
30383
|
+
* copy when the node registers again (only once the hub no longer has it).
|
|
30384
|
+
*/
|
|
30385
|
+
var UninstallNodeOutcomeSchema = _enum([
|
|
30386
|
+
"uninstalled",
|
|
30387
|
+
"not-installed",
|
|
30388
|
+
"refused",
|
|
30389
|
+
"failed",
|
|
30390
|
+
"pending-reconnect"
|
|
30391
|
+
]);
|
|
30392
|
+
var UninstallNodeResultSchema = object({
|
|
30393
|
+
nodeId: string(),
|
|
30394
|
+
outcome: UninstallNodeOutcomeSchema,
|
|
30395
|
+
error: string().optional(),
|
|
30396
|
+
addonIds: array(string()).readonly(),
|
|
30397
|
+
runnersStopped: array(string()).readonly(),
|
|
30398
|
+
warnings: array(string()).readonly()
|
|
30399
|
+
});
|
|
30400
|
+
var UninstallPackageResultSchema = object({
|
|
30401
|
+
/** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
|
|
30402
|
+
success: boolean(),
|
|
30403
|
+
packageName: string(),
|
|
30404
|
+
results: array(UninstallNodeResultSchema).readonly()
|
|
30405
|
+
});
|
|
30406
|
+
/**
|
|
30407
|
+
* `unreachable` lists online agents whose status read FAILED — absence from
|
|
30408
|
+
* `installations` is only "not installed" for a node that answered (D315).
|
|
30409
|
+
*/
|
|
30410
|
+
var PackageInstallationsSchema = object({
|
|
30411
|
+
installations: array(object({
|
|
30412
|
+
packageName: string(),
|
|
30413
|
+
nodeId: string(),
|
|
30414
|
+
nodeName: string(),
|
|
30415
|
+
isHub: boolean(),
|
|
30416
|
+
isOnline: boolean(),
|
|
30417
|
+
version: string().nullable(),
|
|
30418
|
+
addonIds: array(string()).readonly(),
|
|
30419
|
+
source: _enum(["live", "recorded"]),
|
|
30420
|
+
/** The hub installs this package too. `false` on an agent row = an orphan. */
|
|
30421
|
+
onHub: boolean()
|
|
30422
|
+
})).readonly(),
|
|
30423
|
+
unreachable: array(object({
|
|
30424
|
+
nodeId: string(),
|
|
30425
|
+
error: string()
|
|
30426
|
+
})).readonly()
|
|
30427
|
+
});
|
|
30572
30428
|
var BulkUpdateItemStatusSchema = _enum([
|
|
30573
30429
|
"queued",
|
|
30574
30430
|
"updating",
|
|
@@ -30651,10 +30507,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
|
|
|
30651
30507
|
}), method(object({ packageName: string() }), InstallPackageResultSchema, {
|
|
30652
30508
|
kind: "mutation",
|
|
30653
30509
|
auth: "admin"
|
|
30654
|
-
}), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
|
|
30510
|
+
}), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
|
|
30511
|
+
packageName: string().min(1),
|
|
30512
|
+
nodeId: string().optional(),
|
|
30513
|
+
everywhere: boolean().optional()
|
|
30514
|
+
}), UninstallPackageResultSchema, {
|
|
30655
30515
|
kind: "mutation",
|
|
30656
30516
|
auth: "admin"
|
|
30657
|
-
}), method(_void(), ReloadPackagesResultSchema, {
|
|
30517
|
+
}), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
|
|
30658
30518
|
kind: "mutation",
|
|
30659
30519
|
auth: "admin"
|
|
30660
30520
|
}), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
|
|
@@ -39054,6 +38914,12 @@ Object.freeze({
|
|
|
39054
38914
|
addonId: null,
|
|
39055
38915
|
access: "view"
|
|
39056
38916
|
},
|
|
38917
|
+
"addons.listInstallations": {
|
|
38918
|
+
capName: "addons",
|
|
38919
|
+
capScope: "system",
|
|
38920
|
+
addonId: null,
|
|
38921
|
+
access: "view"
|
|
38922
|
+
},
|
|
39057
38923
|
"addons.listJobs": {
|
|
39058
38924
|
capName: "addons",
|
|
39059
38925
|
capScope: "system",
|
|
@@ -40236,90 +40102,18 @@ Object.freeze({
|
|
|
40236
40102
|
addonId: null,
|
|
40237
40103
|
access: "create"
|
|
40238
40104
|
},
|
|
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
40105
|
"decoder.getInfo": {
|
|
40258
40106
|
capName: "decoder",
|
|
40259
40107
|
capScope: "system",
|
|
40260
40108
|
addonId: null,
|
|
40261
40109
|
access: "view"
|
|
40262
40110
|
},
|
|
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
40111
|
"decoder.reprobeHwaccel": {
|
|
40306
40112
|
capName: "decoder",
|
|
40307
40113
|
capScope: "system",
|
|
40308
40114
|
addonId: null,
|
|
40309
40115
|
access: "create"
|
|
40310
40116
|
},
|
|
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
40117
|
"detectionPipeline.applyDeviceSettingsPatch": {
|
|
40324
40118
|
capName: "detection-pipeline",
|
|
40325
40119
|
capScope: "device",
|
|
@@ -45366,12 +45160,6 @@ Object.freeze({
|
|
|
45366
45160
|
addonId: null,
|
|
45367
45161
|
access: "view"
|
|
45368
45162
|
},
|
|
45369
|
-
"streamBroker.pullFrameHandles": {
|
|
45370
|
-
capName: "stream-broker",
|
|
45371
|
-
capScope: "system",
|
|
45372
|
-
addonId: null,
|
|
45373
|
-
access: "view"
|
|
45374
|
-
},
|
|
45375
45163
|
"streamBroker.regenerateRtspToken": {
|
|
45376
45164
|
capName: "stream-broker",
|
|
45377
45165
|
capScope: "system",
|
|
@@ -45438,12 +45226,6 @@ Object.freeze({
|
|
|
45438
45226
|
addonId: null,
|
|
45439
45227
|
access: "create"
|
|
45440
45228
|
},
|
|
45441
|
-
"streamBroker.subscribeFrames": {
|
|
45442
|
-
capName: "stream-broker",
|
|
45443
|
-
capScope: "system",
|
|
45444
|
-
addonId: null,
|
|
45445
|
-
access: "create"
|
|
45446
|
-
},
|
|
45447
45229
|
"streamBroker.unassignProfile": {
|
|
45448
45230
|
capName: "stream-broker",
|
|
45449
45231
|
capScope: "system",
|
|
@@ -45456,12 +45238,6 @@ Object.freeze({
|
|
|
45456
45238
|
addonId: null,
|
|
45457
45239
|
access: "create"
|
|
45458
45240
|
},
|
|
45459
|
-
"streamBroker.unsubscribeFrames": {
|
|
45460
|
-
capName: "stream-broker",
|
|
45461
|
-
capScope: "system",
|
|
45462
|
-
addonId: null,
|
|
45463
|
-
access: "create"
|
|
45464
|
-
},
|
|
45465
45241
|
"streamCatalog.getCatalog": {
|
|
45466
45242
|
capName: "stream-catalog",
|
|
45467
45243
|
capScope: "device",
|
|
@@ -48003,11 +47779,6 @@ Object.freeze({
|
|
|
48003
47779
|
form: "single",
|
|
48004
47780
|
optional: false
|
|
48005
47781
|
}],
|
|
48006
|
-
"decoder.createSession": [{
|
|
48007
|
-
name: "deviceId",
|
|
48008
|
-
form: "single",
|
|
48009
|
-
optional: true
|
|
48010
|
-
}],
|
|
48011
47782
|
"detectionPipeline.applyDeviceSettingsPatch": [{
|
|
48012
47783
|
name: "deviceId",
|
|
48013
47784
|
form: "single",
|
|
@@ -54724,6 +54495,40 @@ var LoadShedController = class LoadShedController {
|
|
|
54724
54495
|
}
|
|
54725
54496
|
};
|
|
54726
54497
|
//#endregion
|
|
54498
|
+
//#region src/default-pool-attribution.ts
|
|
54499
|
+
/** The backend prefix of a `<backend>:<device>` key (bare `cpu` → `cpu`). */
|
|
54500
|
+
function backendOf(deviceKey) {
|
|
54501
|
+
const colon = deviceKey.indexOf(":");
|
|
54502
|
+
return colon >= 0 ? deviceKey.slice(0, colon) : deviceKey;
|
|
54503
|
+
}
|
|
54504
|
+
/**
|
|
54505
|
+
* `load` with its unattributed sessions credited to `eligibleKeys[0]` when that
|
|
54506
|
+
* is the node's ONLY eligible device; `load` itself (same reference) otherwise.
|
|
54507
|
+
* `eligibleKeys` null = the eligible set is not known.
|
|
54508
|
+
*/
|
|
54509
|
+
function attributeDefaultPoolSessions(load, eligibleKeys) {
|
|
54510
|
+
if (eligibleKeys === null || eligibleKeys.length !== 1) return load;
|
|
54511
|
+
const onlyKey = eligibleKeys[0];
|
|
54512
|
+
if (onlyKey === void 0) return load;
|
|
54513
|
+
const attributed = load.devices.reduce((sum, d) => sum + d.attachedCameras, 0);
|
|
54514
|
+
const unattributed = load.attachedCameras - attributed;
|
|
54515
|
+
if (unattributed <= 0) return load;
|
|
54516
|
+
const existing = load.devices.find((d) => d.deviceKey === onlyKey);
|
|
54517
|
+
const credited = existing ? {
|
|
54518
|
+
...existing,
|
|
54519
|
+
attachedCameras: existing.attachedCameras + unattributed
|
|
54520
|
+
} : {
|
|
54521
|
+
deviceKey: onlyKey,
|
|
54522
|
+
backend: backendOf(onlyKey),
|
|
54523
|
+
attachedCameras: unattributed
|
|
54524
|
+
};
|
|
54525
|
+
const devices = [...load.devices.filter((d) => d.deviceKey !== onlyKey), credited].toSorted((a, b) => a.deviceKey.localeCompare(b.deviceKey));
|
|
54526
|
+
return {
|
|
54527
|
+
...load,
|
|
54528
|
+
devices
|
|
54529
|
+
};
|
|
54530
|
+
}
|
|
54531
|
+
//#endregion
|
|
54727
54532
|
//#region src/dispatch-timing.ts
|
|
54728
54533
|
/**
|
|
54729
54534
|
* How long the placement census waits for ONE runner's `getLocalCameras`
|
|
@@ -54790,6 +54595,25 @@ var AgentLoadService = class AgentLoadService {
|
|
|
54790
54595
|
getAgentLoadSummaries() {
|
|
54791
54596
|
return [...this.cachedAgentLoad.values()];
|
|
54792
54597
|
}
|
|
54598
|
+
/**
|
|
54599
|
+
* The cached summaries as the load REPORT (`getAgentLoad`) carries them: a
|
|
54600
|
+
* single-device node's default-pool sessions credited to its one device
|
|
54601
|
+
* (`default-pool-attribution.ts`). The balancer's census
|
|
54602
|
+
* ({@link collectAgentLoad}) stays the runner's raw answer.
|
|
54603
|
+
*/
|
|
54604
|
+
async reportedAgentLoad() {
|
|
54605
|
+
const resolve = this.deps.eligibleDeviceKeys;
|
|
54606
|
+
const summaries = this.getAgentLoadSummaries();
|
|
54607
|
+
if (resolve === void 0) return summaries;
|
|
54608
|
+
return Promise.all(summaries.map(async (summary) => {
|
|
54609
|
+
const eligible = await resolve(summary.nodeId).catch(() => null);
|
|
54610
|
+
const load = attributeDefaultPoolSessions(summary.load, eligible);
|
|
54611
|
+
return load === summary.load ? summary : {
|
|
54612
|
+
...summary,
|
|
54613
|
+
load
|
|
54614
|
+
};
|
|
54615
|
+
}));
|
|
54616
|
+
}
|
|
54793
54617
|
cachedAgentLoadNodeIds() {
|
|
54794
54618
|
return [...this.cachedAgentLoad.keys()];
|
|
54795
54619
|
}
|
|
@@ -57237,8 +57061,7 @@ function mapBroker(brokerResult) {
|
|
|
57237
57061
|
width: p.width,
|
|
57238
57062
|
height: p.height,
|
|
57239
57063
|
subscribers: p.subscribers,
|
|
57240
|
-
inFps: p.inFps
|
|
57241
|
-
outFps: p.outFps
|
|
57064
|
+
inFps: p.inFps
|
|
57242
57065
|
})),
|
|
57243
57066
|
webrtcSessions: brokerResult.webrtcSessions,
|
|
57244
57067
|
rtspRestream: brokerResult.rtspRestream
|
|
@@ -57625,11 +57448,9 @@ var CameraStatusService = class {
|
|
|
57625
57448
|
* `allSlotsFetch` (fetched once by the caller) to avoid a second
|
|
57626
57449
|
* round-trip. Per-slot `getBrokerStats` + `listClients` are fetched in
|
|
57627
57450
|
* 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.
|
|
57451
|
+
* whose `attribution.kind` is one of the `WEBRTC_KINDS`.
|
|
57631
57452
|
*/
|
|
57632
|
-
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57453
|
+
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, sink) {
|
|
57633
57454
|
if (!api || !allSlotsFetch) return Promise.resolve(null);
|
|
57634
57455
|
return this.boundedStage(allSlotsFetch.then(async (slots) => {
|
|
57635
57456
|
const deviceSlots = slots.filter((s) => s.deviceId === deviceId);
|
|
@@ -57646,19 +57467,16 @@ var CameraStatusService = class {
|
|
|
57646
57467
|
clients
|
|
57647
57468
|
};
|
|
57648
57469
|
})), 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
57470
|
return {
|
|
57661
|
-
profiles:
|
|
57471
|
+
profiles: statsAndClients.map(({ slot, stats, clients }) => ({
|
|
57472
|
+
profile: slot.profile,
|
|
57473
|
+
status: slot.status,
|
|
57474
|
+
codec: stats?.codec ?? slot.codec ?? "",
|
|
57475
|
+
width: slot.resolution?.width ?? 0,
|
|
57476
|
+
height: slot.resolution?.height ?? 0,
|
|
57477
|
+
subscribers: clients?.encodedSubscribers ?? 0,
|
|
57478
|
+
inFps: stats?.inputFps ?? null
|
|
57479
|
+
})),
|
|
57662
57480
|
webrtcSessions: statsAndClients.reduce((total, { clients }) => {
|
|
57663
57481
|
if (!clients) return total;
|
|
57664
57482
|
return total + clients.encoded.filter((c) => WEBRTC_KINDS.has(c.attribution.kind)).length;
|
|
@@ -57852,10 +57670,9 @@ var CameraStatusService = class {
|
|
|
57852
57670
|
const api = this.deps.api();
|
|
57853
57671
|
const degradations = { entries: [] };
|
|
57854
57672
|
const { detectionNodeId, sourceNodeId, pinned, detectionReason, audioNodeId, audioPinned } = this.buildAssignmentContext(deviceId);
|
|
57855
|
-
const liveDecoder = { nodeId: null };
|
|
57856
57673
|
const allSlotsFetch = api ? pass.profileSlots(api, sourceNodeId) : null;
|
|
57857
57674
|
const sourceFetch = this.buildSourceStage(api, allSlotsFetch, deviceId, degradations);
|
|
57858
|
-
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57675
|
+
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, degradations);
|
|
57859
57676
|
const decoderFetch = this.buildDecoderStage(detectionNodeId);
|
|
57860
57677
|
const motionResult = this.buildMotionStage(deviceId);
|
|
57861
57678
|
const detectionFetch = this.buildDetectionStage(api, detectionNodeId, deviceId, pass, degradations);
|
|
@@ -57870,11 +57687,10 @@ var CameraStatusService = class {
|
|
|
57870
57687
|
switchesFetch
|
|
57871
57688
|
]);
|
|
57872
57689
|
const audioResult = this.buildAudioStage(audioNodeId, switchedOff);
|
|
57873
|
-
const
|
|
57874
|
-
const decoderNodeId = liveDecoderNodeId ?? detectionNodeId;
|
|
57690
|
+
const decoderNodeId = detectionNodeId;
|
|
57875
57691
|
const reasons = {
|
|
57876
57692
|
detection: detectionReason,
|
|
57877
|
-
decoder:
|
|
57693
|
+
decoder: decoderNodeId !== null ? "co-located" : void 0,
|
|
57878
57694
|
audio: audioPinned ? "manual" : void 0
|
|
57879
57695
|
};
|
|
57880
57696
|
return composeCameraStatus({
|
|
@@ -60111,7 +59927,7 @@ function deviceAsLoad(deviceKey, load) {
|
|
|
60111
59927
|
activeCameras: 0,
|
|
60112
59928
|
avgInferenceFps: 0,
|
|
60113
59929
|
avgInferenceTimeMs: 0,
|
|
60114
|
-
queueDepthTotal:
|
|
59930
|
+
queueDepthTotal: 0,
|
|
60115
59931
|
devices: [],
|
|
60116
59932
|
hardware: { hasGpu: false }
|
|
60117
59933
|
};
|
|
@@ -61091,8 +60907,7 @@ function tallyLoad(load, nodeDelta, perDevice) {
|
|
|
61091
60907
|
}), ...[...perDevice ?? /* @__PURE__ */ new Map()].filter(([deviceKey, delta]) => !known.has(deviceKey) && delta > 0).map(([deviceKey, delta]) => ({
|
|
61092
60908
|
deviceKey,
|
|
61093
60909
|
backend: deviceKey.split(":")[0] ?? deviceKey,
|
|
61094
|
-
attachedCameras: delta
|
|
61095
|
-
queueDepthTotal: 0
|
|
60910
|
+
attachedCameras: delta
|
|
61096
60911
|
}))];
|
|
61097
60912
|
return {
|
|
61098
60913
|
...load,
|
|
@@ -69080,6 +68895,10 @@ async function buildOrchestratorControllers(deps) {
|
|
|
69080
68895
|
onCensus: (entries) => {
|
|
69081
68896
|
motionSliceGate?.noteCensus(entries);
|
|
69082
68897
|
providerSliceGate?.refreshIfStale("runner-census");
|
|
68898
|
+
},
|
|
68899
|
+
eligibleDeviceKeys: async (nodeId) => {
|
|
68900
|
+
const read = await deps.getEligibleInferenceDevicesIfCached(nodeId);
|
|
68901
|
+
return read.kind === "eligible" ? Object.keys(read.eligible) : null;
|
|
69083
68902
|
}
|
|
69084
68903
|
});
|
|
69085
68904
|
/**
|
|
@@ -69938,12 +69757,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
69938
69757
|
id: CLUSTER_MODEL_SECTION_ID,
|
|
69939
69758
|
title: "Enrichment models",
|
|
69940
69759
|
tab: "pipeline",
|
|
69941
|
-
description: "The
|
|
69760
|
+
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
69761
|
fields: [...CLUSTER_MODEL_SCOPED_STEPS.map((step) => ({
|
|
69943
69762
|
key: clusterModelSettingKey(step.stepId),
|
|
69944
69763
|
type: "select",
|
|
69945
69764
|
label: step.label,
|
|
69946
|
-
description: `
|
|
69765
|
+
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
69766
|
options: step.options.map((o) => ({
|
|
69948
69767
|
value: o.id,
|
|
69949
69768
|
label: o.label
|
|
@@ -69965,12 +69784,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
69965
69784
|
id: DETAIL_CROP_SECTION_ID,
|
|
69966
69785
|
title: "Enrichment crop",
|
|
69967
69786
|
tab: "pipeline",
|
|
69968
|
-
description: "How the crop
|
|
69787
|
+
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
69788
|
fields: [{
|
|
69970
69789
|
key: DETAIL_CROP_PADDING_KEY,
|
|
69971
69790
|
type: "slider",
|
|
69972
69791
|
label: "Crop margin",
|
|
69973
|
-
description: "
|
|
69792
|
+
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
69793
|
min: DETAIL_CROP_PADDING_FIELD.min,
|
|
69975
69794
|
max: DETAIL_CROP_PADDING_FIELD.max,
|
|
69976
69795
|
step: DETAIL_CROP_PADDING_FIELD.step,
|
|
@@ -69980,7 +69799,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
69980
69799
|
key: DETAIL_CROP_SQUARE_KEY,
|
|
69981
69800
|
type: "boolean",
|
|
69982
69801
|
label: "Square the crop",
|
|
69983
|
-
description: "
|
|
69802
|
+
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
69803
|
default: DEFAULT_DETAIL_CROP_CONVENTION.square
|
|
69985
69804
|
}]
|
|
69986
69805
|
},
|
|
@@ -69988,13 +69807,13 @@ function buildGlobalSettingsSections(options) {
|
|
|
69988
69807
|
id: NATIVE_LEASE_SECTION_ID,
|
|
69989
69808
|
title: "Native frame lease",
|
|
69990
69809
|
tab: "pipeline",
|
|
69991
|
-
description: "How
|
|
69810
|
+
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
69811
|
fields: [
|
|
69993
69812
|
{
|
|
69994
69813
|
key: NATIVE_LEASE_HOLD_KEY,
|
|
69995
69814
|
type: "slider",
|
|
69996
69815
|
label: "Frames held at once",
|
|
69997
|
-
description: "
|
|
69816
|
+
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
69817
|
min: NATIVE_LEASE_HOLD_FIELD.min,
|
|
69999
69818
|
max: NATIVE_LEASE_HOLD_FIELD.max,
|
|
70000
69819
|
step: NATIVE_LEASE_HOLD_FIELD.step,
|
|
@@ -70006,7 +69825,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70006
69825
|
key: NATIVE_LEASE_TILE_BUDGET_KEY,
|
|
70007
69826
|
type: "slider",
|
|
70008
69827
|
label: "Subject tile RAM",
|
|
70009
|
-
description: "RAM per
|
|
69828
|
+
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
69829
|
min: NATIVE_LEASE_TILE_BUDGET_FIELD.min,
|
|
70011
69830
|
max: NATIVE_LEASE_TILE_BUDGET_FIELD.max,
|
|
70012
69831
|
step: NATIVE_LEASE_TILE_BUDGET_FIELD.step,
|
|
@@ -70018,7 +69837,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70018
69837
|
key: NATIVE_LEASE_SCENE_BUDGET_KEY,
|
|
70019
69838
|
type: "slider",
|
|
70020
69839
|
label: "Scene tile RAM",
|
|
70021
|
-
description: "RAM per
|
|
69840
|
+
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
69841
|
min: NATIVE_LEASE_SCENE_BUDGET_FIELD.min,
|
|
70023
69842
|
max: NATIVE_LEASE_SCENE_BUDGET_FIELD.max,
|
|
70024
69843
|
step: NATIVE_LEASE_SCENE_BUDGET_FIELD.step,
|
|
@@ -70030,7 +69849,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70030
69849
|
key: NATIVE_LEASE_BUDGET_KEY,
|
|
70031
69850
|
type: "slider",
|
|
70032
69851
|
label: "Lease RAM ceiling",
|
|
70033
|
-
description: "
|
|
69852
|
+
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
69853
|
min: NATIVE_LEASE_BUDGET_FIELD.min,
|
|
70035
69854
|
max: NATIVE_LEASE_BUDGET_FIELD.max,
|
|
70036
69855
|
step: NATIVE_LEASE_BUDGET_FIELD.step,
|
|
@@ -70042,7 +69861,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70042
69861
|
key: NATIVE_LEASE_ACTIVITY_KEY,
|
|
70043
69862
|
type: "slider",
|
|
70044
69863
|
label: "Demand window",
|
|
70045
|
-
description: "
|
|
69864
|
+
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
69865
|
min: NATIVE_LEASE_ACTIVITY_FIELD.min,
|
|
70047
69866
|
max: NATIVE_LEASE_ACTIVITY_FIELD.max,
|
|
70048
69867
|
step: NATIVE_LEASE_ACTIVITY_FIELD.step,
|
|
@@ -70055,7 +69874,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70055
69874
|
key: NATIVE_LEASE_ADMISSION_KEY,
|
|
70056
69875
|
type: "select",
|
|
70057
69876
|
label: "What to retain",
|
|
70058
|
-
description: "
|
|
69877
|
+
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
69878
|
options: NATIVE_LEASE_ADMISSION_FIELD.options,
|
|
70060
69879
|
default: NATIVE_LEASE_ADMISSION_FIELD.default
|
|
70061
69880
|
}
|
|
@@ -70068,7 +69887,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70068
69887
|
{
|
|
70069
69888
|
key: "onDisconnect",
|
|
70070
69889
|
type: "select",
|
|
70071
|
-
label: "
|
|
69890
|
+
label: "When a node disconnects",
|
|
69891
|
+
description: "Move its unpinned cameras to other nodes, or leave them stopped.",
|
|
70072
69892
|
default: DEFAULT_FAILOVER_POLICY.onDisconnect,
|
|
70073
69893
|
options: [{
|
|
70074
69894
|
value: "migrate",
|
|
@@ -70081,7 +69901,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70081
69901
|
{
|
|
70082
69902
|
key: "pinnedOnDisconnect",
|
|
70083
69903
|
type: "select",
|
|
70084
|
-
label: "
|
|
69904
|
+
label: "Its pinned cameras",
|
|
69905
|
+
description: "Keep the pin and wait for the node, or drop the pin and move them.",
|
|
70085
69906
|
default: DEFAULT_FAILOVER_POLICY.pinnedOnDisconnect,
|
|
70086
69907
|
options: [{
|
|
70087
69908
|
value: "leave-pinned",
|
|
@@ -70094,7 +69915,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70094
69915
|
{
|
|
70095
69916
|
key: "onReconnect",
|
|
70096
69917
|
type: "select",
|
|
70097
|
-
label: "
|
|
69918
|
+
label: "When it comes back",
|
|
69919
|
+
description: "Put its cameras back where they were, or rebalance the whole cluster.",
|
|
70098
69920
|
default: DEFAULT_FAILOVER_POLICY.onReconnect,
|
|
70099
69921
|
options: [{
|
|
70100
69922
|
value: "restore",
|
|
@@ -72095,7 +71917,7 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
72095
71917
|
async getAgentLoad() {
|
|
72096
71918
|
await this.loadService.refreshDecodeHwaccels();
|
|
72097
71919
|
await this.loadService.collectAgentLoad();
|
|
72098
|
-
return this.loadService.
|
|
71920
|
+
return this.loadService.reportedAgentLoad();
|
|
72099
71921
|
}
|
|
72100
71922
|
async getGlobalMetrics() {
|
|
72101
71923
|
const summaries = await this.getAgentLoad();
|