@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.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
|
});
|
|
@@ -30597,6 +30400,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
|
|
|
30597
30400
|
var RestartAddonResultSchema = unknown();
|
|
30598
30401
|
var InstallPackageResultSchema = unknown();
|
|
30599
30402
|
var ReloadPackagesResultSchema = unknown();
|
|
30403
|
+
/**
|
|
30404
|
+
* What an uninstall did on ONE node.
|
|
30405
|
+
* - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
|
|
30406
|
+
* - `not-installed` — the node did not have it (nothing to do).
|
|
30407
|
+
* - `refused` — protected / bootstrap package; nothing touched.
|
|
30408
|
+
* - `failed` — attempted and did not complete; `error` says why.
|
|
30409
|
+
* - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
|
|
30410
|
+
* back-fill never returns the package, and the stale-addon sweep removes the
|
|
30411
|
+
* copy when the node registers again (only once the hub no longer has it).
|
|
30412
|
+
*/
|
|
30413
|
+
var UninstallNodeOutcomeSchema = _enum([
|
|
30414
|
+
"uninstalled",
|
|
30415
|
+
"not-installed",
|
|
30416
|
+
"refused",
|
|
30417
|
+
"failed",
|
|
30418
|
+
"pending-reconnect"
|
|
30419
|
+
]);
|
|
30420
|
+
var UninstallNodeResultSchema = object({
|
|
30421
|
+
nodeId: string(),
|
|
30422
|
+
outcome: UninstallNodeOutcomeSchema,
|
|
30423
|
+
error: string().optional(),
|
|
30424
|
+
addonIds: array(string()).readonly(),
|
|
30425
|
+
runnersStopped: array(string()).readonly(),
|
|
30426
|
+
warnings: array(string()).readonly()
|
|
30427
|
+
});
|
|
30428
|
+
var UninstallPackageResultSchema = object({
|
|
30429
|
+
/** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
|
|
30430
|
+
success: boolean(),
|
|
30431
|
+
packageName: string(),
|
|
30432
|
+
results: array(UninstallNodeResultSchema).readonly()
|
|
30433
|
+
});
|
|
30434
|
+
/**
|
|
30435
|
+
* `unreachable` lists online agents whose status read FAILED — absence from
|
|
30436
|
+
* `installations` is only "not installed" for a node that answered (D315).
|
|
30437
|
+
*/
|
|
30438
|
+
var PackageInstallationsSchema = object({
|
|
30439
|
+
installations: array(object({
|
|
30440
|
+
packageName: string(),
|
|
30441
|
+
nodeId: string(),
|
|
30442
|
+
nodeName: string(),
|
|
30443
|
+
isHub: boolean(),
|
|
30444
|
+
isOnline: boolean(),
|
|
30445
|
+
version: string().nullable(),
|
|
30446
|
+
addonIds: array(string()).readonly(),
|
|
30447
|
+
source: _enum(["live", "recorded"]),
|
|
30448
|
+
/** The hub installs this package too. `false` on an agent row = an orphan. */
|
|
30449
|
+
onHub: boolean()
|
|
30450
|
+
})).readonly(),
|
|
30451
|
+
unreachable: array(object({
|
|
30452
|
+
nodeId: string(),
|
|
30453
|
+
error: string()
|
|
30454
|
+
})).readonly()
|
|
30455
|
+
});
|
|
30600
30456
|
var BulkUpdateItemStatusSchema = _enum([
|
|
30601
30457
|
"queued",
|
|
30602
30458
|
"updating",
|
|
@@ -30679,10 +30535,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
|
|
|
30679
30535
|
}), method(object({ packageName: string() }), InstallPackageResultSchema, {
|
|
30680
30536
|
kind: "mutation",
|
|
30681
30537
|
auth: "admin"
|
|
30682
|
-
}), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
|
|
30538
|
+
}), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
|
|
30539
|
+
packageName: string().min(1),
|
|
30540
|
+
nodeId: string().optional(),
|
|
30541
|
+
everywhere: boolean().optional()
|
|
30542
|
+
}), UninstallPackageResultSchema, {
|
|
30683
30543
|
kind: "mutation",
|
|
30684
30544
|
auth: "admin"
|
|
30685
|
-
}), method(_void(), ReloadPackagesResultSchema, {
|
|
30545
|
+
}), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
|
|
30686
30546
|
kind: "mutation",
|
|
30687
30547
|
auth: "admin"
|
|
30688
30548
|
}), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
|
|
@@ -39082,6 +38942,12 @@ Object.freeze({
|
|
|
39082
38942
|
addonId: null,
|
|
39083
38943
|
access: "view"
|
|
39084
38944
|
},
|
|
38945
|
+
"addons.listInstallations": {
|
|
38946
|
+
capName: "addons",
|
|
38947
|
+
capScope: "system",
|
|
38948
|
+
addonId: null,
|
|
38949
|
+
access: "view"
|
|
38950
|
+
},
|
|
39085
38951
|
"addons.listJobs": {
|
|
39086
38952
|
capName: "addons",
|
|
39087
38953
|
capScope: "system",
|
|
@@ -40264,90 +40130,18 @@ Object.freeze({
|
|
|
40264
40130
|
addonId: null,
|
|
40265
40131
|
access: "create"
|
|
40266
40132
|
},
|
|
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
40133
|
"decoder.getInfo": {
|
|
40286
40134
|
capName: "decoder",
|
|
40287
40135
|
capScope: "system",
|
|
40288
40136
|
addonId: null,
|
|
40289
40137
|
access: "view"
|
|
40290
40138
|
},
|
|
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
40139
|
"decoder.reprobeHwaccel": {
|
|
40334
40140
|
capName: "decoder",
|
|
40335
40141
|
capScope: "system",
|
|
40336
40142
|
addonId: null,
|
|
40337
40143
|
access: "create"
|
|
40338
40144
|
},
|
|
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
40145
|
"detectionPipeline.applyDeviceSettingsPatch": {
|
|
40352
40146
|
capName: "detection-pipeline",
|
|
40353
40147
|
capScope: "device",
|
|
@@ -45394,12 +45188,6 @@ Object.freeze({
|
|
|
45394
45188
|
addonId: null,
|
|
45395
45189
|
access: "view"
|
|
45396
45190
|
},
|
|
45397
|
-
"streamBroker.pullFrameHandles": {
|
|
45398
|
-
capName: "stream-broker",
|
|
45399
|
-
capScope: "system",
|
|
45400
|
-
addonId: null,
|
|
45401
|
-
access: "view"
|
|
45402
|
-
},
|
|
45403
45191
|
"streamBroker.regenerateRtspToken": {
|
|
45404
45192
|
capName: "stream-broker",
|
|
45405
45193
|
capScope: "system",
|
|
@@ -45466,12 +45254,6 @@ Object.freeze({
|
|
|
45466
45254
|
addonId: null,
|
|
45467
45255
|
access: "create"
|
|
45468
45256
|
},
|
|
45469
|
-
"streamBroker.subscribeFrames": {
|
|
45470
|
-
capName: "stream-broker",
|
|
45471
|
-
capScope: "system",
|
|
45472
|
-
addonId: null,
|
|
45473
|
-
access: "create"
|
|
45474
|
-
},
|
|
45475
45257
|
"streamBroker.unassignProfile": {
|
|
45476
45258
|
capName: "stream-broker",
|
|
45477
45259
|
capScope: "system",
|
|
@@ -45484,12 +45266,6 @@ Object.freeze({
|
|
|
45484
45266
|
addonId: null,
|
|
45485
45267
|
access: "create"
|
|
45486
45268
|
},
|
|
45487
|
-
"streamBroker.unsubscribeFrames": {
|
|
45488
|
-
capName: "stream-broker",
|
|
45489
|
-
capScope: "system",
|
|
45490
|
-
addonId: null,
|
|
45491
|
-
access: "create"
|
|
45492
|
-
},
|
|
45493
45269
|
"streamCatalog.getCatalog": {
|
|
45494
45270
|
capName: "stream-catalog",
|
|
45495
45271
|
capScope: "device",
|
|
@@ -48031,11 +47807,6 @@ Object.freeze({
|
|
|
48031
47807
|
form: "single",
|
|
48032
47808
|
optional: false
|
|
48033
47809
|
}],
|
|
48034
|
-
"decoder.createSession": [{
|
|
48035
|
-
name: "deviceId",
|
|
48036
|
-
form: "single",
|
|
48037
|
-
optional: true
|
|
48038
|
-
}],
|
|
48039
47810
|
"detectionPipeline.applyDeviceSettingsPatch": [{
|
|
48040
47811
|
name: "deviceId",
|
|
48041
47812
|
form: "single",
|
|
@@ -54752,6 +54523,40 @@ var LoadShedController = class LoadShedController {
|
|
|
54752
54523
|
}
|
|
54753
54524
|
};
|
|
54754
54525
|
//#endregion
|
|
54526
|
+
//#region src/default-pool-attribution.ts
|
|
54527
|
+
/** The backend prefix of a `<backend>:<device>` key (bare `cpu` → `cpu`). */
|
|
54528
|
+
function backendOf(deviceKey) {
|
|
54529
|
+
const colon = deviceKey.indexOf(":");
|
|
54530
|
+
return colon >= 0 ? deviceKey.slice(0, colon) : deviceKey;
|
|
54531
|
+
}
|
|
54532
|
+
/**
|
|
54533
|
+
* `load` with its unattributed sessions credited to `eligibleKeys[0]` when that
|
|
54534
|
+
* is the node's ONLY eligible device; `load` itself (same reference) otherwise.
|
|
54535
|
+
* `eligibleKeys` null = the eligible set is not known.
|
|
54536
|
+
*/
|
|
54537
|
+
function attributeDefaultPoolSessions(load, eligibleKeys) {
|
|
54538
|
+
if (eligibleKeys === null || eligibleKeys.length !== 1) return load;
|
|
54539
|
+
const onlyKey = eligibleKeys[0];
|
|
54540
|
+
if (onlyKey === void 0) return load;
|
|
54541
|
+
const attributed = load.devices.reduce((sum, d) => sum + d.attachedCameras, 0);
|
|
54542
|
+
const unattributed = load.attachedCameras - attributed;
|
|
54543
|
+
if (unattributed <= 0) return load;
|
|
54544
|
+
const existing = load.devices.find((d) => d.deviceKey === onlyKey);
|
|
54545
|
+
const credited = existing ? {
|
|
54546
|
+
...existing,
|
|
54547
|
+
attachedCameras: existing.attachedCameras + unattributed
|
|
54548
|
+
} : {
|
|
54549
|
+
deviceKey: onlyKey,
|
|
54550
|
+
backend: backendOf(onlyKey),
|
|
54551
|
+
attachedCameras: unattributed
|
|
54552
|
+
};
|
|
54553
|
+
const devices = [...load.devices.filter((d) => d.deviceKey !== onlyKey), credited].toSorted((a, b) => a.deviceKey.localeCompare(b.deviceKey));
|
|
54554
|
+
return {
|
|
54555
|
+
...load,
|
|
54556
|
+
devices
|
|
54557
|
+
};
|
|
54558
|
+
}
|
|
54559
|
+
//#endregion
|
|
54755
54560
|
//#region src/dispatch-timing.ts
|
|
54756
54561
|
/**
|
|
54757
54562
|
* How long the placement census waits for ONE runner's `getLocalCameras`
|
|
@@ -54818,6 +54623,25 @@ var AgentLoadService = class AgentLoadService {
|
|
|
54818
54623
|
getAgentLoadSummaries() {
|
|
54819
54624
|
return [...this.cachedAgentLoad.values()];
|
|
54820
54625
|
}
|
|
54626
|
+
/**
|
|
54627
|
+
* The cached summaries as the load REPORT (`getAgentLoad`) carries them: a
|
|
54628
|
+
* single-device node's default-pool sessions credited to its one device
|
|
54629
|
+
* (`default-pool-attribution.ts`). The balancer's census
|
|
54630
|
+
* ({@link collectAgentLoad}) stays the runner's raw answer.
|
|
54631
|
+
*/
|
|
54632
|
+
async reportedAgentLoad() {
|
|
54633
|
+
const resolve = this.deps.eligibleDeviceKeys;
|
|
54634
|
+
const summaries = this.getAgentLoadSummaries();
|
|
54635
|
+
if (resolve === void 0) return summaries;
|
|
54636
|
+
return Promise.all(summaries.map(async (summary) => {
|
|
54637
|
+
const eligible = await resolve(summary.nodeId).catch(() => null);
|
|
54638
|
+
const load = attributeDefaultPoolSessions(summary.load, eligible);
|
|
54639
|
+
return load === summary.load ? summary : {
|
|
54640
|
+
...summary,
|
|
54641
|
+
load
|
|
54642
|
+
};
|
|
54643
|
+
}));
|
|
54644
|
+
}
|
|
54821
54645
|
cachedAgentLoadNodeIds() {
|
|
54822
54646
|
return [...this.cachedAgentLoad.keys()];
|
|
54823
54647
|
}
|
|
@@ -57265,8 +57089,7 @@ function mapBroker(brokerResult) {
|
|
|
57265
57089
|
width: p.width,
|
|
57266
57090
|
height: p.height,
|
|
57267
57091
|
subscribers: p.subscribers,
|
|
57268
|
-
inFps: p.inFps
|
|
57269
|
-
outFps: p.outFps
|
|
57092
|
+
inFps: p.inFps
|
|
57270
57093
|
})),
|
|
57271
57094
|
webrtcSessions: brokerResult.webrtcSessions,
|
|
57272
57095
|
rtspRestream: brokerResult.rtspRestream
|
|
@@ -57653,11 +57476,9 @@ var CameraStatusService = class {
|
|
|
57653
57476
|
* `allSlotsFetch` (fetched once by the caller) to avoid a second
|
|
57654
57477
|
* round-trip. Per-slot `getBrokerStats` + `listClients` are fetched in
|
|
57655
57478
|
* 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.
|
|
57479
|
+
* whose `attribution.kind` is one of the `WEBRTC_KINDS`.
|
|
57659
57480
|
*/
|
|
57660
|
-
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57481
|
+
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, sink) {
|
|
57661
57482
|
if (!api || !allSlotsFetch) return Promise.resolve(null);
|
|
57662
57483
|
return this.boundedStage(allSlotsFetch.then(async (slots) => {
|
|
57663
57484
|
const deviceSlots = slots.filter((s) => s.deviceId === deviceId);
|
|
@@ -57674,19 +57495,16 @@ var CameraStatusService = class {
|
|
|
57674
57495
|
clients
|
|
57675
57496
|
};
|
|
57676
57497
|
})), 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
57498
|
return {
|
|
57689
|
-
profiles:
|
|
57499
|
+
profiles: statsAndClients.map(({ slot, stats, clients }) => ({
|
|
57500
|
+
profile: slot.profile,
|
|
57501
|
+
status: slot.status,
|
|
57502
|
+
codec: stats?.codec ?? slot.codec ?? "",
|
|
57503
|
+
width: slot.resolution?.width ?? 0,
|
|
57504
|
+
height: slot.resolution?.height ?? 0,
|
|
57505
|
+
subscribers: clients?.encodedSubscribers ?? 0,
|
|
57506
|
+
inFps: stats?.inputFps ?? null
|
|
57507
|
+
})),
|
|
57690
57508
|
webrtcSessions: statsAndClients.reduce((total, { clients }) => {
|
|
57691
57509
|
if (!clients) return total;
|
|
57692
57510
|
return total + clients.encoded.filter((c) => WEBRTC_KINDS.has(c.attribution.kind)).length;
|
|
@@ -57880,10 +57698,9 @@ var CameraStatusService = class {
|
|
|
57880
57698
|
const api = this.deps.api();
|
|
57881
57699
|
const degradations = { entries: [] };
|
|
57882
57700
|
const { detectionNodeId, sourceNodeId, pinned, detectionReason, audioNodeId, audioPinned } = this.buildAssignmentContext(deviceId);
|
|
57883
|
-
const liveDecoder = { nodeId: null };
|
|
57884
57701
|
const allSlotsFetch = api ? pass.profileSlots(api, sourceNodeId) : null;
|
|
57885
57702
|
const sourceFetch = this.buildSourceStage(api, allSlotsFetch, deviceId, degradations);
|
|
57886
|
-
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57703
|
+
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, degradations);
|
|
57887
57704
|
const decoderFetch = this.buildDecoderStage(detectionNodeId);
|
|
57888
57705
|
const motionResult = this.buildMotionStage(deviceId);
|
|
57889
57706
|
const detectionFetch = this.buildDetectionStage(api, detectionNodeId, deviceId, pass, degradations);
|
|
@@ -57898,11 +57715,10 @@ var CameraStatusService = class {
|
|
|
57898
57715
|
switchesFetch
|
|
57899
57716
|
]);
|
|
57900
57717
|
const audioResult = this.buildAudioStage(audioNodeId, switchedOff);
|
|
57901
|
-
const
|
|
57902
|
-
const decoderNodeId = liveDecoderNodeId ?? detectionNodeId;
|
|
57718
|
+
const decoderNodeId = detectionNodeId;
|
|
57903
57719
|
const reasons = {
|
|
57904
57720
|
detection: detectionReason,
|
|
57905
|
-
decoder:
|
|
57721
|
+
decoder: decoderNodeId !== null ? "co-located" : void 0,
|
|
57906
57722
|
audio: audioPinned ? "manual" : void 0
|
|
57907
57723
|
};
|
|
57908
57724
|
return composeCameraStatus({
|
|
@@ -60139,7 +59955,7 @@ function deviceAsLoad(deviceKey, load) {
|
|
|
60139
59955
|
activeCameras: 0,
|
|
60140
59956
|
avgInferenceFps: 0,
|
|
60141
59957
|
avgInferenceTimeMs: 0,
|
|
60142
|
-
queueDepthTotal:
|
|
59958
|
+
queueDepthTotal: 0,
|
|
60143
59959
|
devices: [],
|
|
60144
59960
|
hardware: { hasGpu: false }
|
|
60145
59961
|
};
|
|
@@ -61119,8 +60935,7 @@ function tallyLoad(load, nodeDelta, perDevice) {
|
|
|
61119
60935
|
}), ...[...perDevice ?? /* @__PURE__ */ new Map()].filter(([deviceKey, delta]) => !known.has(deviceKey) && delta > 0).map(([deviceKey, delta]) => ({
|
|
61120
60936
|
deviceKey,
|
|
61121
60937
|
backend: deviceKey.split(":")[0] ?? deviceKey,
|
|
61122
|
-
attachedCameras: delta
|
|
61123
|
-
queueDepthTotal: 0
|
|
60938
|
+
attachedCameras: delta
|
|
61124
60939
|
}))];
|
|
61125
60940
|
return {
|
|
61126
60941
|
...load,
|
|
@@ -69108,6 +68923,10 @@ async function buildOrchestratorControllers(deps) {
|
|
|
69108
68923
|
onCensus: (entries) => {
|
|
69109
68924
|
motionSliceGate?.noteCensus(entries);
|
|
69110
68925
|
providerSliceGate?.refreshIfStale("runner-census");
|
|
68926
|
+
},
|
|
68927
|
+
eligibleDeviceKeys: async (nodeId) => {
|
|
68928
|
+
const read = await deps.getEligibleInferenceDevicesIfCached(nodeId);
|
|
68929
|
+
return read.kind === "eligible" ? Object.keys(read.eligible) : null;
|
|
69111
68930
|
}
|
|
69112
68931
|
});
|
|
69113
68932
|
/**
|
|
@@ -69966,12 +69785,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
69966
69785
|
id: CLUSTER_MODEL_SECTION_ID,
|
|
69967
69786
|
title: "Enrichment models",
|
|
69968
69787
|
tab: "pipeline",
|
|
69969
|
-
description: "The
|
|
69788
|
+
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
69789
|
fields: [...CLUSTER_MODEL_SCOPED_STEPS.map((step) => ({
|
|
69971
69790
|
key: clusterModelSettingKey(step.stepId),
|
|
69972
69791
|
type: "select",
|
|
69973
69792
|
label: step.label,
|
|
69974
|
-
description: `
|
|
69793
|
+
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
69794
|
options: step.options.map((o) => ({
|
|
69976
69795
|
value: o.id,
|
|
69977
69796
|
label: o.label
|
|
@@ -69993,12 +69812,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
69993
69812
|
id: DETAIL_CROP_SECTION_ID,
|
|
69994
69813
|
title: "Enrichment crop",
|
|
69995
69814
|
tab: "pipeline",
|
|
69996
|
-
description: "How the crop
|
|
69815
|
+
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
69816
|
fields: [{
|
|
69998
69817
|
key: DETAIL_CROP_PADDING_KEY,
|
|
69999
69818
|
type: "slider",
|
|
70000
69819
|
label: "Crop margin",
|
|
70001
|
-
description: "
|
|
69820
|
+
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
69821
|
min: DETAIL_CROP_PADDING_FIELD.min,
|
|
70003
69822
|
max: DETAIL_CROP_PADDING_FIELD.max,
|
|
70004
69823
|
step: DETAIL_CROP_PADDING_FIELD.step,
|
|
@@ -70008,7 +69827,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70008
69827
|
key: DETAIL_CROP_SQUARE_KEY,
|
|
70009
69828
|
type: "boolean",
|
|
70010
69829
|
label: "Square the crop",
|
|
70011
|
-
description: "
|
|
69830
|
+
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
69831
|
default: DEFAULT_DETAIL_CROP_CONVENTION.square
|
|
70013
69832
|
}]
|
|
70014
69833
|
},
|
|
@@ -70016,13 +69835,13 @@ function buildGlobalSettingsSections(options) {
|
|
|
70016
69835
|
id: NATIVE_LEASE_SECTION_ID,
|
|
70017
69836
|
title: "Native frame lease",
|
|
70018
69837
|
tab: "pipeline",
|
|
70019
|
-
description: "How
|
|
69838
|
+
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
69839
|
fields: [
|
|
70021
69840
|
{
|
|
70022
69841
|
key: NATIVE_LEASE_HOLD_KEY,
|
|
70023
69842
|
type: "slider",
|
|
70024
69843
|
label: "Frames held at once",
|
|
70025
|
-
description: "
|
|
69844
|
+
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
69845
|
min: NATIVE_LEASE_HOLD_FIELD.min,
|
|
70027
69846
|
max: NATIVE_LEASE_HOLD_FIELD.max,
|
|
70028
69847
|
step: NATIVE_LEASE_HOLD_FIELD.step,
|
|
@@ -70034,7 +69853,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70034
69853
|
key: NATIVE_LEASE_TILE_BUDGET_KEY,
|
|
70035
69854
|
type: "slider",
|
|
70036
69855
|
label: "Subject tile RAM",
|
|
70037
|
-
description: "RAM per
|
|
69856
|
+
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
69857
|
min: NATIVE_LEASE_TILE_BUDGET_FIELD.min,
|
|
70039
69858
|
max: NATIVE_LEASE_TILE_BUDGET_FIELD.max,
|
|
70040
69859
|
step: NATIVE_LEASE_TILE_BUDGET_FIELD.step,
|
|
@@ -70046,7 +69865,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70046
69865
|
key: NATIVE_LEASE_SCENE_BUDGET_KEY,
|
|
70047
69866
|
type: "slider",
|
|
70048
69867
|
label: "Scene tile RAM",
|
|
70049
|
-
description: "RAM per
|
|
69868
|
+
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
69869
|
min: NATIVE_LEASE_SCENE_BUDGET_FIELD.min,
|
|
70051
69870
|
max: NATIVE_LEASE_SCENE_BUDGET_FIELD.max,
|
|
70052
69871
|
step: NATIVE_LEASE_SCENE_BUDGET_FIELD.step,
|
|
@@ -70058,7 +69877,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70058
69877
|
key: NATIVE_LEASE_BUDGET_KEY,
|
|
70059
69878
|
type: "slider",
|
|
70060
69879
|
label: "Lease RAM ceiling",
|
|
70061
|
-
description: "
|
|
69880
|
+
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
69881
|
min: NATIVE_LEASE_BUDGET_FIELD.min,
|
|
70063
69882
|
max: NATIVE_LEASE_BUDGET_FIELD.max,
|
|
70064
69883
|
step: NATIVE_LEASE_BUDGET_FIELD.step,
|
|
@@ -70070,7 +69889,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70070
69889
|
key: NATIVE_LEASE_ACTIVITY_KEY,
|
|
70071
69890
|
type: "slider",
|
|
70072
69891
|
label: "Demand window",
|
|
70073
|
-
description: "
|
|
69892
|
+
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
69893
|
min: NATIVE_LEASE_ACTIVITY_FIELD.min,
|
|
70075
69894
|
max: NATIVE_LEASE_ACTIVITY_FIELD.max,
|
|
70076
69895
|
step: NATIVE_LEASE_ACTIVITY_FIELD.step,
|
|
@@ -70083,7 +69902,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70083
69902
|
key: NATIVE_LEASE_ADMISSION_KEY,
|
|
70084
69903
|
type: "select",
|
|
70085
69904
|
label: "What to retain",
|
|
70086
|
-
description: "
|
|
69905
|
+
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
69906
|
options: NATIVE_LEASE_ADMISSION_FIELD.options,
|
|
70088
69907
|
default: NATIVE_LEASE_ADMISSION_FIELD.default
|
|
70089
69908
|
}
|
|
@@ -70096,7 +69915,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70096
69915
|
{
|
|
70097
69916
|
key: "onDisconnect",
|
|
70098
69917
|
type: "select",
|
|
70099
|
-
label: "
|
|
69918
|
+
label: "When a node disconnects",
|
|
69919
|
+
description: "Move its unpinned cameras to other nodes, or leave them stopped.",
|
|
70100
69920
|
default: DEFAULT_FAILOVER_POLICY.onDisconnect,
|
|
70101
69921
|
options: [{
|
|
70102
69922
|
value: "migrate",
|
|
@@ -70109,7 +69929,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70109
69929
|
{
|
|
70110
69930
|
key: "pinnedOnDisconnect",
|
|
70111
69931
|
type: "select",
|
|
70112
|
-
label: "
|
|
69932
|
+
label: "Its pinned cameras",
|
|
69933
|
+
description: "Keep the pin and wait for the node, or drop the pin and move them.",
|
|
70113
69934
|
default: DEFAULT_FAILOVER_POLICY.pinnedOnDisconnect,
|
|
70114
69935
|
options: [{
|
|
70115
69936
|
value: "leave-pinned",
|
|
@@ -70122,7 +69943,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70122
69943
|
{
|
|
70123
69944
|
key: "onReconnect",
|
|
70124
69945
|
type: "select",
|
|
70125
|
-
label: "
|
|
69946
|
+
label: "When it comes back",
|
|
69947
|
+
description: "Put its cameras back where they were, or rebalance the whole cluster.",
|
|
70126
69948
|
default: DEFAULT_FAILOVER_POLICY.onReconnect,
|
|
70127
69949
|
options: [{
|
|
70128
69950
|
value: "restore",
|
|
@@ -72123,7 +71945,7 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
72123
71945
|
async getAgentLoad() {
|
|
72124
71946
|
await this.loadService.refreshDecodeHwaccels();
|
|
72125
71947
|
await this.loadService.collectAgentLoad();
|
|
72126
|
-
return this.loadService.
|
|
71948
|
+
return this.loadService.reportedAgentLoad();
|
|
72127
71949
|
}
|
|
72128
71950
|
async getGlobalMetrics() {
|
|
72129
71951
|
const summaries = await this.getAgentLoad();
|