@camstack/addon-pipeline-orchestrator 1.2.294 → 1.2.296
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_stub.js +51 -51
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-BSs0jnDe.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-ClO9DjMF.mjs} +3 -3
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_types__loadShare__.js-BAA5Kwgx.mjs +26 -0
- package/dist/_virtual_mf___mfe_internal__addon_pipeline_orchestrator_widgets__loadShare___mf_0_camstack_mf_1_ui_mf_2_library__loadShare__.js-BGNuYCGq.mjs +26 -0
- package/dist/{hostInit-DB2QUonn.mjs → hostInit-cCd7B0HK.mjs} +3 -3
- package/dist/index.js +153 -640
- package/dist/index.mjs +153 -640
- 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-CXr4GmWP.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-DqL6noYf.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,
|
|
@@ -24400,21 +24195,6 @@ var PipelineDefaultStepSchema = lazy(() => object({
|
|
|
24400
24195
|
group: string().optional(),
|
|
24401
24196
|
settings: record(string(), unknown()).optional()
|
|
24402
24197
|
}));
|
|
24403
|
-
var PipelineTemplateStepSchema = lazy(() => object({
|
|
24404
|
-
addonId: string(),
|
|
24405
|
-
enabled: boolean(),
|
|
24406
|
-
modelId: string(),
|
|
24407
|
-
children: array(PipelineTemplateStepSchema).readonly(),
|
|
24408
|
-
settings: record(string(), unknown()).optional()
|
|
24409
|
-
}));
|
|
24410
|
-
var PipelineTemplateSchema$1 = object({
|
|
24411
|
-
id: string(),
|
|
24412
|
-
name: string(),
|
|
24413
|
-
createdAt: string(),
|
|
24414
|
-
updatedAt: string(),
|
|
24415
|
-
engine: PipelineEngineChoiceSchema,
|
|
24416
|
-
steps: array(PipelineTemplateStepSchema).readonly()
|
|
24417
|
-
});
|
|
24418
24198
|
var PipelineModelOptionSchema = object({
|
|
24419
24199
|
id: string(),
|
|
24420
24200
|
name: string(),
|
|
@@ -24736,18 +24516,6 @@ var pipelineExecutorCapability = {
|
|
|
24736
24516
|
steps: array(PipelineStepInputSchema),
|
|
24737
24517
|
deviceKey: string().optional()
|
|
24738
24518
|
}), PipelineValidationResultSchema),
|
|
24739
|
-
listTemplates: method(_void(), array(PipelineTemplateSchema$1).readonly()),
|
|
24740
|
-
saveTemplate: method(object({
|
|
24741
|
-
name: string(),
|
|
24742
|
-
steps: array(PipelineTemplateStepSchema).readonly(),
|
|
24743
|
-
engine: PipelineEngineChoiceSchema
|
|
24744
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
24745
|
-
updateTemplate: method(object({
|
|
24746
|
-
id: string(),
|
|
24747
|
-
name: string().optional(),
|
|
24748
|
-
steps: array(PipelineTemplateStepSchema).readonly().optional()
|
|
24749
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
24750
|
-
deleteTemplate: method(object({ id: string() }), _void(), { kind: "mutation" }),
|
|
24751
24519
|
getCapabilities: method(_void(), InferenceCapabilitiesBridge),
|
|
24752
24520
|
getAddonModels: method(object({ addonId: string() }), ModelAvailabilityListBridge),
|
|
24753
24521
|
downloadModel: method(object({
|
|
@@ -26507,14 +26275,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
26507
26275
|
* Per-inference-device live load (multi-device C4). One entry per deviceKey
|
|
26508
26276
|
* this runner currently has attached cameras on, so the orchestrator's second
|
|
26509
26277
|
* `balance()` pass (over a node's devices) weights on real per-pool session
|
|
26510
|
-
* counts. Empty on single-device / pre-multi-device runners.
|
|
26511
|
-
* 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).
|
|
26512
26282
|
*/
|
|
26513
26283
|
devices: array(object({
|
|
26514
26284
|
deviceKey: string(),
|
|
26515
26285
|
backend: string(),
|
|
26516
|
-
attachedCameras: number()
|
|
26517
|
-
queueDepthTotal: number()
|
|
26286
|
+
attachedCameras: number()
|
|
26518
26287
|
})).default([]),
|
|
26519
26288
|
/** Hardware capability flags reported by this node. */
|
|
26520
26289
|
hardware: object({
|
|
@@ -26728,14 +26497,6 @@ var CameraPipelineConfigSchema = object({
|
|
|
26728
26497
|
settings: record(string(), unknown()).readonly().optional()
|
|
26729
26498
|
}).nullable().optional()
|
|
26730
26499
|
});
|
|
26731
|
-
var PipelineTemplateSchema = object({
|
|
26732
|
-
id: string(),
|
|
26733
|
-
name: string(),
|
|
26734
|
-
description: string().optional(),
|
|
26735
|
-
config: CameraPipelineConfigSchema,
|
|
26736
|
-
createdAt: string(),
|
|
26737
|
-
updatedAt: string()
|
|
26738
|
-
});
|
|
26739
26500
|
var DeviceStepConfigSchema = object({
|
|
26740
26501
|
modelId: string().optional(),
|
|
26741
26502
|
settings: record(string(), unknown()).optional(),
|
|
@@ -26845,7 +26606,10 @@ var PipelineAssignmentSchema = object({
|
|
|
26845
26606
|
});
|
|
26846
26607
|
/**
|
|
26847
26608
|
* Per-agent load summary surfaced to the load balancer + dashboards.
|
|
26848
|
-
* 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.
|
|
26849
26613
|
*/
|
|
26850
26614
|
var AgentLoadSummarySchema = object({
|
|
26851
26615
|
nodeId: string(),
|
|
@@ -26934,26 +26698,27 @@ var CameraBrokerStatusSchema = object({
|
|
|
26934
26698
|
width: number(),
|
|
26935
26699
|
height: number(),
|
|
26936
26700
|
subscribers: number(),
|
|
26937
|
-
|
|
26938
|
-
|
|
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()
|
|
26939
26709
|
})).readonly(),
|
|
26940
26710
|
webrtcSessions: number(),
|
|
26941
26711
|
rtspRestream: boolean()
|
|
26942
26712
|
});
|
|
26943
|
-
/**
|
|
26944
|
-
|
|
26945
|
-
|
|
26946
|
-
|
|
26947
|
-
|
|
26948
|
-
|
|
26949
|
-
|
|
26950
|
-
|
|
26951
|
-
var CameraDecoderStatusSchema = object({
|
|
26952
|
-
nodeId: string(),
|
|
26953
|
-
formats: array(string()).readonly(),
|
|
26954
|
-
sessionCount: number(),
|
|
26955
|
-
shm: CameraDecoderShmSchema
|
|
26956
|
-
});
|
|
26713
|
+
/**
|
|
26714
|
+
* Decoder block — WHERE decode runs (co-located with the detection node by
|
|
26715
|
+
* construction); null when the camera has no detection node. It carries no
|
|
26716
|
+
* frame counter: the shared-memory plane whose counters it used to serve is
|
|
26717
|
+
* gone, and those fields read 0 forever. Whether frames actually flow is read
|
|
26718
|
+
* from `detection.actualFps` (frames delivered to and processed by the
|
|
26719
|
+
* detector), never from a counter nothing feeds.
|
|
26720
|
+
*/
|
|
26721
|
+
var CameraDecoderStatusSchema = object({ nodeId: string() });
|
|
26957
26722
|
/** Motion block — null when motion detection is not active for this device. */
|
|
26958
26723
|
var CameraMotionStatusSchema = object({
|
|
26959
26724
|
enabled: boolean(),
|
|
@@ -27807,33 +27572,7 @@ var pipelineOrchestratorCapability = {
|
|
|
27807
27572
|
auth: "admin"
|
|
27808
27573
|
}),
|
|
27809
27574
|
/** Snapshot of the in-flight or last disk-wins fleet reconcile. */
|
|
27810
|
-
getReconcileFromDiskStatus: method(_void(), DiskReconcileJobSchema, { auth: "admin" })
|
|
27811
|
-
/** List every template the operator has saved. */
|
|
27812
|
-
listTemplates: method(_void(), array(PipelineTemplateSchema).readonly()),
|
|
27813
|
-
/** Create a new named preset from a given CameraPipelineConfig. */
|
|
27814
|
-
saveTemplate: method(object({
|
|
27815
|
-
name: string(),
|
|
27816
|
-
description: string().optional(),
|
|
27817
|
-
config: CameraPipelineConfigSchema
|
|
27818
|
-
}), PipelineTemplateSchema, {
|
|
27819
|
-
kind: "mutation",
|
|
27820
|
-
auth: "admin"
|
|
27821
|
-
}),
|
|
27822
|
-
/** Partial update of a template. Any omitted field is preserved. */
|
|
27823
|
-
updateTemplate: method(object({
|
|
27824
|
-
id: string(),
|
|
27825
|
-
name: string().optional(),
|
|
27826
|
-
description: string().optional(),
|
|
27827
|
-
config: CameraPipelineConfigSchema.optional()
|
|
27828
|
-
}), PipelineTemplateSchema, {
|
|
27829
|
-
kind: "mutation",
|
|
27830
|
-
auth: "admin"
|
|
27831
|
-
}),
|
|
27832
|
-
/** Remove a template. Camera configs that were seeded from it keep a copy. */
|
|
27833
|
-
deleteTemplate: method(object({ id: string() }), object({ success: literal(true) }), {
|
|
27834
|
-
kind: "mutation",
|
|
27835
|
-
auth: "admin"
|
|
27836
|
-
})
|
|
27575
|
+
getReconcileFromDiskStatus: method(_void(), DiskReconcileJobSchema, { auth: "admin" })
|
|
27837
27576
|
}
|
|
27838
27577
|
};
|
|
27839
27578
|
/**
|
|
@@ -30055,8 +29794,6 @@ var WebrtcStreamChoiceSchema = object({
|
|
|
30055
29794
|
]).nullable(),
|
|
30056
29795
|
/** Input FPS from the camera (null for adaptive). */
|
|
30057
29796
|
inputFps: number().nullable(),
|
|
30058
|
-
/** Decoded FPS (null for adaptive). */
|
|
30059
|
-
decodeFps: number().nullable(),
|
|
30060
29797
|
/** Bitrate in kbps (null for adaptive). */
|
|
30061
29798
|
bitrateKbps: number().nullable()
|
|
30062
29799
|
});
|
|
@@ -40302,90 +40039,18 @@ Object.freeze({
|
|
|
40302
40039
|
addonId: null,
|
|
40303
40040
|
access: "create"
|
|
40304
40041
|
},
|
|
40305
|
-
"decoder.createSession": {
|
|
40306
|
-
capName: "decoder",
|
|
40307
|
-
capScope: "system",
|
|
40308
|
-
addonId: null,
|
|
40309
|
-
access: "view"
|
|
40310
|
-
},
|
|
40311
|
-
"decoder.destroySession": {
|
|
40312
|
-
capName: "decoder",
|
|
40313
|
-
capScope: "system",
|
|
40314
|
-
addonId: null,
|
|
40315
|
-
access: "delete"
|
|
40316
|
-
},
|
|
40317
|
-
"decoder.getFrame": {
|
|
40318
|
-
capName: "decoder",
|
|
40319
|
-
capScope: "system",
|
|
40320
|
-
addonId: null,
|
|
40321
|
-
access: "view"
|
|
40322
|
-
},
|
|
40323
40042
|
"decoder.getInfo": {
|
|
40324
40043
|
capName: "decoder",
|
|
40325
40044
|
capScope: "system",
|
|
40326
40045
|
addonId: null,
|
|
40327
40046
|
access: "view"
|
|
40328
40047
|
},
|
|
40329
|
-
"decoder.getShmStats": {
|
|
40330
|
-
capName: "decoder",
|
|
40331
|
-
capScope: "system",
|
|
40332
|
-
addonId: null,
|
|
40333
|
-
access: "view"
|
|
40334
|
-
},
|
|
40335
|
-
"decoder.getStats": {
|
|
40336
|
-
capName: "decoder",
|
|
40337
|
-
capScope: "system",
|
|
40338
|
-
addonId: null,
|
|
40339
|
-
access: "view"
|
|
40340
|
-
},
|
|
40341
|
-
"decoder.listActiveSessions": {
|
|
40342
|
-
capName: "decoder",
|
|
40343
|
-
capScope: "system",
|
|
40344
|
-
addonId: null,
|
|
40345
|
-
access: "view"
|
|
40346
|
-
},
|
|
40347
|
-
"decoder.openStream": {
|
|
40348
|
-
capName: "decoder",
|
|
40349
|
-
capScope: "system",
|
|
40350
|
-
addonId: null,
|
|
40351
|
-
access: "view"
|
|
40352
|
-
},
|
|
40353
|
-
"decoder.pullFrames": {
|
|
40354
|
-
capName: "decoder",
|
|
40355
|
-
capScope: "system",
|
|
40356
|
-
addonId: null,
|
|
40357
|
-
access: "view"
|
|
40358
|
-
},
|
|
40359
|
-
"decoder.pullHandles": {
|
|
40360
|
-
capName: "decoder",
|
|
40361
|
-
capScope: "system",
|
|
40362
|
-
addonId: null,
|
|
40363
|
-
access: "view"
|
|
40364
|
-
},
|
|
40365
|
-
"decoder.pushPacket": {
|
|
40366
|
-
capName: "decoder",
|
|
40367
|
-
capScope: "system",
|
|
40368
|
-
addonId: null,
|
|
40369
|
-
access: "view"
|
|
40370
|
-
},
|
|
40371
40048
|
"decoder.reprobeHwaccel": {
|
|
40372
40049
|
capName: "decoder",
|
|
40373
40050
|
capScope: "system",
|
|
40374
40051
|
addonId: null,
|
|
40375
40052
|
access: "create"
|
|
40376
40053
|
},
|
|
40377
|
-
"decoder.supportsCodec": {
|
|
40378
|
-
capName: "decoder",
|
|
40379
|
-
capScope: "system",
|
|
40380
|
-
addonId: null,
|
|
40381
|
-
access: "view"
|
|
40382
|
-
},
|
|
40383
|
-
"decoder.updateConfig": {
|
|
40384
|
-
capName: "decoder",
|
|
40385
|
-
capScope: "system",
|
|
40386
|
-
addonId: null,
|
|
40387
|
-
access: "view"
|
|
40388
|
-
},
|
|
40389
40054
|
"detectionPipeline.applyDeviceSettingsPatch": {
|
|
40390
40055
|
capName: "detection-pipeline",
|
|
40391
40056
|
capScope: "device",
|
|
@@ -43476,12 +43141,6 @@ Object.freeze({
|
|
|
43476
43141
|
addonId: null,
|
|
43477
43142
|
access: "delete"
|
|
43478
43143
|
},
|
|
43479
|
-
"pipelineExecutor.deleteTemplate": {
|
|
43480
|
-
capName: "pipeline-executor",
|
|
43481
|
-
capScope: "system",
|
|
43482
|
-
addonId: null,
|
|
43483
|
-
access: "delete"
|
|
43484
|
-
},
|
|
43485
43144
|
"pipelineExecutor.downloadModel": {
|
|
43486
43145
|
capName: "pipeline-executor",
|
|
43487
43146
|
capScope: "system",
|
|
@@ -43620,12 +43279,6 @@ Object.freeze({
|
|
|
43620
43279
|
addonId: null,
|
|
43621
43280
|
access: "view"
|
|
43622
43281
|
},
|
|
43623
|
-
"pipelineExecutor.listTemplates": {
|
|
43624
|
-
capName: "pipeline-executor",
|
|
43625
|
-
capScope: "system",
|
|
43626
|
-
addonId: null,
|
|
43627
|
-
access: "view"
|
|
43628
|
-
},
|
|
43629
43282
|
"pipelineExecutor.rearmInferenceDevice": {
|
|
43630
43283
|
capName: "pipeline-executor",
|
|
43631
43284
|
capScope: "system",
|
|
@@ -43650,12 +43303,6 @@ Object.freeze({
|
|
|
43650
43303
|
addonId: null,
|
|
43651
43304
|
access: "create"
|
|
43652
43305
|
},
|
|
43653
|
-
"pipelineExecutor.saveTemplate": {
|
|
43654
|
-
capName: "pipeline-executor",
|
|
43655
|
-
capScope: "system",
|
|
43656
|
-
addonId: null,
|
|
43657
|
-
access: "create"
|
|
43658
|
-
},
|
|
43659
43306
|
"pipelineExecutor.setVideoPipelineSteps": {
|
|
43660
43307
|
capName: "pipeline-executor",
|
|
43661
43308
|
capScope: "system",
|
|
@@ -43674,12 +43321,6 @@ Object.freeze({
|
|
|
43674
43321
|
addonId: null,
|
|
43675
43322
|
access: "create"
|
|
43676
43323
|
},
|
|
43677
|
-
"pipelineExecutor.updateTemplate": {
|
|
43678
|
-
capName: "pipeline-executor",
|
|
43679
|
-
capScope: "system",
|
|
43680
|
-
addonId: null,
|
|
43681
|
-
access: "create"
|
|
43682
|
-
},
|
|
43683
43324
|
"pipelineExecutor.validatePipeline": {
|
|
43684
43325
|
capName: "pipeline-executor",
|
|
43685
43326
|
capScope: "system",
|
|
@@ -43710,12 +43351,6 @@ Object.freeze({
|
|
|
43710
43351
|
addonId: null,
|
|
43711
43352
|
access: "create"
|
|
43712
43353
|
},
|
|
43713
|
-
"pipelineOrchestrator.deleteTemplate": {
|
|
43714
|
-
capName: "pipeline-orchestrator",
|
|
43715
|
-
capScope: "system",
|
|
43716
|
-
addonId: null,
|
|
43717
|
-
access: "delete"
|
|
43718
|
-
},
|
|
43719
43354
|
"pipelineOrchestrator.getAgentLoad": {
|
|
43720
43355
|
capName: "pipeline-orchestrator",
|
|
43721
43356
|
capScope: "system",
|
|
@@ -43866,12 +43501,6 @@ Object.freeze({
|
|
|
43866
43501
|
addonId: null,
|
|
43867
43502
|
access: "view"
|
|
43868
43503
|
},
|
|
43869
|
-
"pipelineOrchestrator.listTemplates": {
|
|
43870
|
-
capName: "pipeline-orchestrator",
|
|
43871
|
-
capScope: "system",
|
|
43872
|
-
addonId: null,
|
|
43873
|
-
access: "view"
|
|
43874
|
-
},
|
|
43875
43504
|
"pipelineOrchestrator.pauseForStorageMigration": {
|
|
43876
43505
|
capName: "pipeline-orchestrator",
|
|
43877
43506
|
capScope: "system",
|
|
@@ -43926,12 +43555,6 @@ Object.freeze({
|
|
|
43926
43555
|
addonId: null,
|
|
43927
43556
|
access: "create"
|
|
43928
43557
|
},
|
|
43929
|
-
"pipelineOrchestrator.saveTemplate": {
|
|
43930
|
-
capName: "pipeline-orchestrator",
|
|
43931
|
-
capScope: "system",
|
|
43932
|
-
addonId: null,
|
|
43933
|
-
access: "create"
|
|
43934
|
-
},
|
|
43935
43558
|
"pipelineOrchestrator.setAgentCapabilities": {
|
|
43936
43559
|
capName: "pipeline-orchestrator",
|
|
43937
43560
|
capScope: "system",
|
|
@@ -44040,12 +43663,6 @@ Object.freeze({
|
|
|
44040
43663
|
addonId: null,
|
|
44041
43664
|
access: "create"
|
|
44042
43665
|
},
|
|
44043
|
-
"pipelineOrchestrator.updateTemplate": {
|
|
44044
|
-
capName: "pipeline-orchestrator",
|
|
44045
|
-
capScope: "system",
|
|
44046
|
-
addonId: null,
|
|
44047
|
-
access: "create"
|
|
44048
|
-
},
|
|
44049
43666
|
"pipelineRunner.attachCamera": {
|
|
44050
43667
|
capName: "pipeline-runner",
|
|
44051
43668
|
capScope: "system",
|
|
@@ -45480,12 +45097,6 @@ Object.freeze({
|
|
|
45480
45097
|
addonId: null,
|
|
45481
45098
|
access: "view"
|
|
45482
45099
|
},
|
|
45483
|
-
"streamBroker.pullFrameHandles": {
|
|
45484
|
-
capName: "stream-broker",
|
|
45485
|
-
capScope: "system",
|
|
45486
|
-
addonId: null,
|
|
45487
|
-
access: "view"
|
|
45488
|
-
},
|
|
45489
45100
|
"streamBroker.regenerateRtspToken": {
|
|
45490
45101
|
capName: "stream-broker",
|
|
45491
45102
|
capScope: "system",
|
|
@@ -45552,12 +45163,6 @@ Object.freeze({
|
|
|
45552
45163
|
addonId: null,
|
|
45553
45164
|
access: "create"
|
|
45554
45165
|
},
|
|
45555
|
-
"streamBroker.subscribeFrames": {
|
|
45556
|
-
capName: "stream-broker",
|
|
45557
|
-
capScope: "system",
|
|
45558
|
-
addonId: null,
|
|
45559
|
-
access: "create"
|
|
45560
|
-
},
|
|
45561
45166
|
"streamBroker.unassignProfile": {
|
|
45562
45167
|
capName: "stream-broker",
|
|
45563
45168
|
capScope: "system",
|
|
@@ -45570,12 +45175,6 @@ Object.freeze({
|
|
|
45570
45175
|
addonId: null,
|
|
45571
45176
|
access: "create"
|
|
45572
45177
|
},
|
|
45573
|
-
"streamBroker.unsubscribeFrames": {
|
|
45574
|
-
capName: "stream-broker",
|
|
45575
|
-
capScope: "system",
|
|
45576
|
-
addonId: null,
|
|
45577
|
-
access: "create"
|
|
45578
|
-
},
|
|
45579
45178
|
"streamCatalog.getCatalog": {
|
|
45580
45179
|
capName: "stream-catalog",
|
|
45581
45180
|
capScope: "device",
|
|
@@ -48117,11 +47716,6 @@ Object.freeze({
|
|
|
48117
47716
|
form: "single",
|
|
48118
47717
|
optional: false
|
|
48119
47718
|
}],
|
|
48120
|
-
"decoder.createSession": [{
|
|
48121
|
-
name: "deviceId",
|
|
48122
|
-
form: "single",
|
|
48123
|
-
optional: true
|
|
48124
|
-
}],
|
|
48125
47719
|
"detectionPipeline.applyDeviceSettingsPatch": [{
|
|
48126
47720
|
name: "deviceId",
|
|
48127
47721
|
form: "single",
|
|
@@ -54838,6 +54432,40 @@ var LoadShedController = class LoadShedController {
|
|
|
54838
54432
|
}
|
|
54839
54433
|
};
|
|
54840
54434
|
//#endregion
|
|
54435
|
+
//#region src/default-pool-attribution.ts
|
|
54436
|
+
/** The backend prefix of a `<backend>:<device>` key (bare `cpu` → `cpu`). */
|
|
54437
|
+
function backendOf(deviceKey) {
|
|
54438
|
+
const colon = deviceKey.indexOf(":");
|
|
54439
|
+
return colon >= 0 ? deviceKey.slice(0, colon) : deviceKey;
|
|
54440
|
+
}
|
|
54441
|
+
/**
|
|
54442
|
+
* `load` with its unattributed sessions credited to `eligibleKeys[0]` when that
|
|
54443
|
+
* is the node's ONLY eligible device; `load` itself (same reference) otherwise.
|
|
54444
|
+
* `eligibleKeys` null = the eligible set is not known.
|
|
54445
|
+
*/
|
|
54446
|
+
function attributeDefaultPoolSessions(load, eligibleKeys) {
|
|
54447
|
+
if (eligibleKeys === null || eligibleKeys.length !== 1) return load;
|
|
54448
|
+
const onlyKey = eligibleKeys[0];
|
|
54449
|
+
if (onlyKey === void 0) return load;
|
|
54450
|
+
const attributed = load.devices.reduce((sum, d) => sum + d.attachedCameras, 0);
|
|
54451
|
+
const unattributed = load.attachedCameras - attributed;
|
|
54452
|
+
if (unattributed <= 0) return load;
|
|
54453
|
+
const existing = load.devices.find((d) => d.deviceKey === onlyKey);
|
|
54454
|
+
const credited = existing ? {
|
|
54455
|
+
...existing,
|
|
54456
|
+
attachedCameras: existing.attachedCameras + unattributed
|
|
54457
|
+
} : {
|
|
54458
|
+
deviceKey: onlyKey,
|
|
54459
|
+
backend: backendOf(onlyKey),
|
|
54460
|
+
attachedCameras: unattributed
|
|
54461
|
+
};
|
|
54462
|
+
const devices = [...load.devices.filter((d) => d.deviceKey !== onlyKey), credited].toSorted((a, b) => a.deviceKey.localeCompare(b.deviceKey));
|
|
54463
|
+
return {
|
|
54464
|
+
...load,
|
|
54465
|
+
devices
|
|
54466
|
+
};
|
|
54467
|
+
}
|
|
54468
|
+
//#endregion
|
|
54841
54469
|
//#region src/dispatch-timing.ts
|
|
54842
54470
|
/**
|
|
54843
54471
|
* How long the placement census waits for ONE runner's `getLocalCameras`
|
|
@@ -54904,6 +54532,25 @@ var AgentLoadService = class AgentLoadService {
|
|
|
54904
54532
|
getAgentLoadSummaries() {
|
|
54905
54533
|
return [...this.cachedAgentLoad.values()];
|
|
54906
54534
|
}
|
|
54535
|
+
/**
|
|
54536
|
+
* The cached summaries as the load REPORT (`getAgentLoad`) carries them: a
|
|
54537
|
+
* single-device node's default-pool sessions credited to its one device
|
|
54538
|
+
* (`default-pool-attribution.ts`). The balancer's census
|
|
54539
|
+
* ({@link collectAgentLoad}) stays the runner's raw answer.
|
|
54540
|
+
*/
|
|
54541
|
+
async reportedAgentLoad() {
|
|
54542
|
+
const resolve = this.deps.eligibleDeviceKeys;
|
|
54543
|
+
const summaries = this.getAgentLoadSummaries();
|
|
54544
|
+
if (resolve === void 0) return summaries;
|
|
54545
|
+
return Promise.all(summaries.map(async (summary) => {
|
|
54546
|
+
const eligible = await resolve(summary.nodeId).catch(() => null);
|
|
54547
|
+
const load = attributeDefaultPoolSessions(summary.load, eligible);
|
|
54548
|
+
return load === summary.load ? summary : {
|
|
54549
|
+
...summary,
|
|
54550
|
+
load
|
|
54551
|
+
};
|
|
54552
|
+
}));
|
|
54553
|
+
}
|
|
54907
54554
|
cachedAgentLoadNodeIds() {
|
|
54908
54555
|
return [...this.cachedAgentLoad.keys()];
|
|
54909
54556
|
}
|
|
@@ -57351,29 +56998,15 @@ function mapBroker(brokerResult) {
|
|
|
57351
56998
|
width: p.width,
|
|
57352
56999
|
height: p.height,
|
|
57353
57000
|
subscribers: p.subscribers,
|
|
57354
|
-
inFps: p.inFps
|
|
57355
|
-
outFps: p.outFps
|
|
57001
|
+
inFps: p.inFps
|
|
57356
57002
|
})),
|
|
57357
57003
|
webrtcSessions: brokerResult.webrtcSessions,
|
|
57358
57004
|
rtspRestream: brokerResult.rtspRestream
|
|
57359
57005
|
};
|
|
57360
57006
|
}
|
|
57361
|
-
function mapDecoderShm(shm) {
|
|
57362
|
-
return {
|
|
57363
|
-
framesWritten: shm.framesWritten,
|
|
57364
|
-
getFrameHits: shm.getFrameHits,
|
|
57365
|
-
getFrameMisses: shm.getFrameMisses,
|
|
57366
|
-
budgetMb: shm.budgetMb
|
|
57367
|
-
};
|
|
57368
|
-
}
|
|
57369
57007
|
function mapDecoder(decoderResult) {
|
|
57370
57008
|
if (decoderResult === null) return null;
|
|
57371
|
-
return {
|
|
57372
|
-
nodeId: decoderResult.nodeId,
|
|
57373
|
-
formats: [...decoderResult.formats],
|
|
57374
|
-
sessionCount: decoderResult.sessionCount,
|
|
57375
|
-
shm: mapDecoderShm(decoderResult.shm)
|
|
57376
|
-
};
|
|
57009
|
+
return { nodeId: decoderResult.nodeId };
|
|
57377
57010
|
}
|
|
57378
57011
|
function mapMotion(motionResult) {
|
|
57379
57012
|
if (motionResult === null) return null;
|
|
@@ -57752,11 +57385,9 @@ var CameraStatusService = class {
|
|
|
57752
57385
|
* `allSlotsFetch` (fetched once by the caller) to avoid a second
|
|
57753
57386
|
* round-trip. Per-slot `getBrokerStats` + `listClients` are fetched in
|
|
57754
57387
|
* parallel. WebRTC sessions are counted by filtering `encoded[]` entries
|
|
57755
|
-
* whose `attribution.kind` is one of the `WEBRTC_KINDS`.
|
|
57756
|
-
* broker's actual decode-session node into `liveDecoder` (T6) — the first
|
|
57757
|
-
* slot that reports one wins.
|
|
57388
|
+
* whose `attribution.kind` is one of the `WEBRTC_KINDS`.
|
|
57758
57389
|
*/
|
|
57759
|
-
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57390
|
+
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, sink) {
|
|
57760
57391
|
if (!api || !allSlotsFetch) return Promise.resolve(null);
|
|
57761
57392
|
return this.boundedStage(allSlotsFetch.then(async (slots) => {
|
|
57762
57393
|
const deviceSlots = slots.filter((s) => s.deviceId === deviceId);
|
|
@@ -57773,19 +57404,16 @@ var CameraStatusService = class {
|
|
|
57773
57404
|
clients
|
|
57774
57405
|
};
|
|
57775
57406
|
})), pass.rtspEntries(api, sourceNodeId).catch(() => null)]);
|
|
57776
|
-
const profileDetails = statsAndClients.map(({ slot, stats, clients }) => ({
|
|
57777
|
-
profile: slot.profile,
|
|
57778
|
-
status: slot.status,
|
|
57779
|
-
codec: stats?.codec ?? slot.codec ?? "",
|
|
57780
|
-
width: slot.resolution?.width ?? 0,
|
|
57781
|
-
height: slot.resolution?.height ?? 0,
|
|
57782
|
-
subscribers: clients?.encodedSubscribers ?? 0,
|
|
57783
|
-
inFps: stats?.inputFps ?? 0,
|
|
57784
|
-
outFps: stats?.decodeFps ?? 0
|
|
57785
|
-
}));
|
|
57786
|
-
for (const { stats } of statsAndClients) if (liveDecoder.nodeId === null && typeof stats?.decoderNodeId === "string") liveDecoder.nodeId = stats.decoderNodeId;
|
|
57787
57407
|
return {
|
|
57788
|
-
profiles:
|
|
57408
|
+
profiles: statsAndClients.map(({ slot, stats, clients }) => ({
|
|
57409
|
+
profile: slot.profile,
|
|
57410
|
+
status: slot.status,
|
|
57411
|
+
codec: stats?.codec ?? slot.codec ?? "",
|
|
57412
|
+
width: slot.resolution?.width ?? 0,
|
|
57413
|
+
height: slot.resolution?.height ?? 0,
|
|
57414
|
+
subscribers: clients?.encodedSubscribers ?? 0,
|
|
57415
|
+
inFps: stats?.inputFps ?? null
|
|
57416
|
+
})),
|
|
57789
57417
|
webrtcSessions: statsAndClients.reduce((total, { clients }) => {
|
|
57790
57418
|
if (!clients) return total;
|
|
57791
57419
|
return total + clients.encoded.filter((c) => WEBRTC_KINDS.has(c.attribution.kind)).length;
|
|
@@ -57797,27 +57425,19 @@ var CameraStatusService = class {
|
|
|
57797
57425
|
}), STAGE_TIMEOUT_MS, "broker", deviceId, sink);
|
|
57798
57426
|
}
|
|
57799
57427
|
/**
|
|
57800
|
-
* Decoder stage
|
|
57801
|
-
*
|
|
57802
|
-
*
|
|
57803
|
-
*
|
|
57804
|
-
*
|
|
57805
|
-
*
|
|
57806
|
-
*
|
|
57807
|
-
*
|
|
57428
|
+
* Decoder stage: the node decode runs on BY CONSTRUCTION — the detection
|
|
57429
|
+
* node (decode is always co-located with its frame consumer). Unassigned
|
|
57430
|
+
* camera → null. (The ASSIGNMENT block upgrades to the broker's live session
|
|
57431
|
+
* node when observed — see the T6 post-processing in `getCameraStatus`.)
|
|
57432
|
+
*
|
|
57433
|
+
* No counter rides along. This block used to serve shared-memory ring stats,
|
|
57434
|
+
* session count and formats hard-coded to 0 / [] after the SHM frame plane
|
|
57435
|
+
* was retired (frames live in the in-RAM RetainedFrameStore), and the admin
|
|
57436
|
+
* UI raised "decode path stalled" on every active camera from those zeros.
|
|
57437
|
+
* Frames reaching the detector are read from `detection.actualFps`.
|
|
57808
57438
|
*/
|
|
57809
57439
|
buildDecoderStage(detectionNodeId) {
|
|
57810
|
-
return detectionNodeId ?
|
|
57811
|
-
nodeId: detectionNodeId,
|
|
57812
|
-
formats: [],
|
|
57813
|
-
sessionCount: 0,
|
|
57814
|
-
shm: {
|
|
57815
|
-
framesWritten: 0,
|
|
57816
|
-
getFrameHits: 0,
|
|
57817
|
-
getFrameMisses: 0,
|
|
57818
|
-
budgetMb: 0
|
|
57819
|
-
}
|
|
57820
|
-
}) : Promise.resolve(null);
|
|
57440
|
+
return Promise.resolve(detectionNodeId ? { nodeId: detectionNodeId } : null);
|
|
57821
57441
|
}
|
|
57822
57442
|
/**
|
|
57823
57443
|
* Motion stage (from cached runner config). Motion configuration lives in
|
|
@@ -57987,10 +57607,9 @@ var CameraStatusService = class {
|
|
|
57987
57607
|
const api = this.deps.api();
|
|
57988
57608
|
const degradations = { entries: [] };
|
|
57989
57609
|
const { detectionNodeId, sourceNodeId, pinned, detectionReason, audioNodeId, audioPinned } = this.buildAssignmentContext(deviceId);
|
|
57990
|
-
const liveDecoder = { nodeId: null };
|
|
57991
57610
|
const allSlotsFetch = api ? pass.profileSlots(api, sourceNodeId) : null;
|
|
57992
57611
|
const sourceFetch = this.buildSourceStage(api, allSlotsFetch, deviceId, degradations);
|
|
57993
|
-
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57612
|
+
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, degradations);
|
|
57994
57613
|
const decoderFetch = this.buildDecoderStage(detectionNodeId);
|
|
57995
57614
|
const motionResult = this.buildMotionStage(deviceId);
|
|
57996
57615
|
const detectionFetch = this.buildDetectionStage(api, detectionNodeId, deviceId, pass, degradations);
|
|
@@ -58005,11 +57624,10 @@ var CameraStatusService = class {
|
|
|
58005
57624
|
switchesFetch
|
|
58006
57625
|
]);
|
|
58007
57626
|
const audioResult = this.buildAudioStage(audioNodeId, switchedOff);
|
|
58008
|
-
const
|
|
58009
|
-
const decoderNodeId = liveDecoderNodeId ?? detectionNodeId;
|
|
57627
|
+
const decoderNodeId = detectionNodeId;
|
|
58010
57628
|
const reasons = {
|
|
58011
57629
|
detection: detectionReason,
|
|
58012
|
-
decoder:
|
|
57630
|
+
decoder: decoderNodeId !== null ? "co-located" : void 0,
|
|
58013
57631
|
audio: audioPinned ? "manual" : void 0
|
|
58014
57632
|
};
|
|
58015
57633
|
return composeCameraStatus({
|
|
@@ -60246,7 +59864,7 @@ function deviceAsLoad(deviceKey, load) {
|
|
|
60246
59864
|
activeCameras: 0,
|
|
60247
59865
|
avgInferenceFps: 0,
|
|
60248
59866
|
avgInferenceTimeMs: 0,
|
|
60249
|
-
queueDepthTotal:
|
|
59867
|
+
queueDepthTotal: 0,
|
|
60250
59868
|
devices: [],
|
|
60251
59869
|
hardware: { hasGpu: false }
|
|
60252
59870
|
};
|
|
@@ -61226,8 +60844,7 @@ function tallyLoad(load, nodeDelta, perDevice) {
|
|
|
61226
60844
|
}), ...[...perDevice ?? /* @__PURE__ */ new Map()].filter(([deviceKey, delta]) => !known.has(deviceKey) && delta > 0).map(([deviceKey, delta]) => ({
|
|
61227
60845
|
deviceKey,
|
|
61228
60846
|
backend: deviceKey.split(":")[0] ?? deviceKey,
|
|
61229
|
-
attachedCameras: delta
|
|
61230
|
-
queueDepthTotal: 0
|
|
60847
|
+
attachedCameras: delta
|
|
61231
60848
|
}))];
|
|
61232
60849
|
return {
|
|
61233
60850
|
...load,
|
|
@@ -64348,8 +63965,8 @@ function migrateCameraSettings(cameraMap) {
|
|
|
64348
63965
|
* refused rather than substituted (D54). Reset happens to the STORE, before
|
|
64349
63966
|
* anything is resolved.
|
|
64350
63967
|
*
|
|
64351
|
-
*
|
|
64352
|
-
*
|
|
63968
|
+
* The wholesale `pipelineByAgent` override is not swept: it carries step
|
|
63969
|
+
* STRUCTURE only, and provisioning never reads a `modelId` from it.
|
|
64353
63970
|
*/
|
|
64354
63971
|
/** The one predicate: a pin to a deleted catalog id that no custom model owns. */
|
|
64355
63972
|
function pinNamesRemovedModel(stepId, modelId, isCustom) {
|
|
@@ -64598,8 +64215,7 @@ async function redispatchAffected(deps, cleared) {
|
|
|
64598
64215
|
/**
|
|
64599
64216
|
* `orchestrator-store-schemas.ts` — whole-blob Zod schemas for the
|
|
64600
64217
|
* orchestrator's addon-store keys that persist an ENTIRE collection
|
|
64601
|
-
* under a single key (`nodeBindings`, `
|
|
64602
|
-
* `cameraSettings`).
|
|
64218
|
+
* under a single key (`nodeBindings`, `agentSettings`, `cameraSettings`).
|
|
64603
64219
|
*
|
|
64604
64220
|
* These back the durable-state primitive (`this.state(KEY, Schema, {})`)
|
|
64605
64221
|
* so a hand-written serializer can never silently drop a field on save:
|
|
@@ -64612,32 +64228,7 @@ async function redispatchAffected(deps, cleared) {
|
|
|
64612
64228
|
* falls back to the empty map on a whole-blob parse failure, so the
|
|
64613
64229
|
* schema is kept faithful to the on-disk shape rather than overly strict.
|
|
64614
64230
|
*/
|
|
64615
|
-
var EngineChoiceSchema = object({
|
|
64616
|
-
runtime: _enum(["python", "node"]).transform(() => "python"),
|
|
64617
|
-
backend: string(),
|
|
64618
|
-
format: string(),
|
|
64619
|
-
device: string().optional()
|
|
64620
|
-
});
|
|
64621
64231
|
var NodeBindingsSchema = record(string(), record(string(), string()));
|
|
64622
|
-
var StoredPipelineConfigSchema = object({
|
|
64623
|
-
engine: EngineChoiceSchema.optional(),
|
|
64624
|
-
steps: array(PipelineStepInputSchema).readonly(),
|
|
64625
|
-
audio: object({
|
|
64626
|
-
engine: EngineChoiceSchema.optional(),
|
|
64627
|
-
modelId: string().optional(),
|
|
64628
|
-
enabled: boolean(),
|
|
64629
|
-
settings: record(string(), unknown()).readonly().optional()
|
|
64630
|
-
}).nullable().optional()
|
|
64631
|
-
});
|
|
64632
|
-
var StoredPipelineTemplateSchema = object({
|
|
64633
|
-
id: string(),
|
|
64634
|
-
name: string(),
|
|
64635
|
-
description: string().optional(),
|
|
64636
|
-
config: StoredPipelineConfigSchema,
|
|
64637
|
-
createdAt: string(),
|
|
64638
|
-
updatedAt: string()
|
|
64639
|
-
});
|
|
64640
|
-
var TemplatesSchema = record(string(), StoredPipelineTemplateSchema);
|
|
64641
64232
|
var StoredAgentAddonConfigSchema = object({
|
|
64642
64233
|
enabled: boolean(),
|
|
64643
64234
|
modelId: string().optional(),
|
|
@@ -64742,7 +64333,6 @@ var PipelineSettingsStore = class PipelineSettingsStore {
|
|
|
64742
64333
|
blobWriteLock = new KeyedAsyncLock({ isShuttingDown: () => this.disposed });
|
|
64743
64334
|
static AGENT_SETTINGS_LOCK_KEY = "agentSettings";
|
|
64744
64335
|
_nodeBindingsState = null;
|
|
64745
|
-
_templatesState = null;
|
|
64746
64336
|
_agentSettingsState = null;
|
|
64747
64337
|
_cameraSettingsState = null;
|
|
64748
64338
|
_bindingsMigrationDoneState = null;
|
|
@@ -64751,10 +64341,6 @@ var PipelineSettingsStore = class PipelineSettingsStore {
|
|
|
64751
64341
|
if (!this._nodeBindingsState) this._nodeBindingsState = this.deps.state("nodeBindings", NodeBindingsSchema, {});
|
|
64752
64342
|
return this._nodeBindingsState;
|
|
64753
64343
|
}
|
|
64754
|
-
get templatesState() {
|
|
64755
|
-
if (!this._templatesState) this._templatesState = this.deps.state("templates", TemplatesSchema, {});
|
|
64756
|
-
return this._templatesState;
|
|
64757
|
-
}
|
|
64758
64344
|
get agentSettingsState() {
|
|
64759
64345
|
if (!this._agentSettingsState) this._agentSettingsState = this.deps.state("agentSettings", AgentSettingsMapSchema, {});
|
|
64760
64346
|
return this._agentSettingsState;
|
|
@@ -65037,59 +64623,6 @@ var PipelineSettingsStore = class PipelineSettingsStore {
|
|
|
65037
64623
|
return rest;
|
|
65038
64624
|
});
|
|
65039
64625
|
}
|
|
65040
|
-
/** Read the templates map from the addon store via the durable handle. */
|
|
65041
|
-
async readTemplatesMap() {
|
|
65042
|
-
const raw = await this.templatesState.get();
|
|
65043
|
-
const out = {};
|
|
65044
|
-
for (const [key, value] of Object.entries(raw)) if (this.isPipelineTemplate(value)) out[key] = value;
|
|
65045
|
-
return out;
|
|
65046
|
-
}
|
|
65047
|
-
async listTemplates() {
|
|
65048
|
-
const templates = await this.readTemplatesMap();
|
|
65049
|
-
return Object.values(templates).slice().toSorted((a, b) => a.name.localeCompare(b.name));
|
|
65050
|
-
}
|
|
65051
|
-
async saveTemplate(input) {
|
|
65052
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
65053
|
-
const template = {
|
|
65054
|
-
id: this.generateTemplateId(),
|
|
65055
|
-
name: input.name,
|
|
65056
|
-
description: input.description,
|
|
65057
|
-
config: input.config,
|
|
65058
|
-
createdAt: now,
|
|
65059
|
-
updatedAt: now
|
|
65060
|
-
};
|
|
65061
|
-
const templates = await this.readTemplatesMap();
|
|
65062
|
-
templates[template.id] = template;
|
|
65063
|
-
await this.templatesState.set(templates);
|
|
65064
|
-
this.deps.logger.info("template saved", { meta: {
|
|
65065
|
-
templateId: template.id,
|
|
65066
|
-
name: template.name
|
|
65067
|
-
} });
|
|
65068
|
-
return template;
|
|
65069
|
-
}
|
|
65070
|
-
async updateTemplate(input) {
|
|
65071
|
-
const templates = await this.readTemplatesMap();
|
|
65072
|
-
const existing = templates[input.id];
|
|
65073
|
-
if (!existing) throw new Error(`updateTemplate: template '${input.id}' not found`);
|
|
65074
|
-
const next = {
|
|
65075
|
-
...existing,
|
|
65076
|
-
...input.name !== void 0 ? { name: input.name } : {},
|
|
65077
|
-
...input.description !== void 0 ? { description: input.description } : {},
|
|
65078
|
-
...input.config !== void 0 ? { config: input.config } : {},
|
|
65079
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
65080
|
-
};
|
|
65081
|
-
templates[input.id] = next;
|
|
65082
|
-
await this.templatesState.set(templates);
|
|
65083
|
-
return next;
|
|
65084
|
-
}
|
|
65085
|
-
async deleteTemplate(input) {
|
|
65086
|
-
const templates = await this.readTemplatesMap();
|
|
65087
|
-
if (!templates[input.id]) return { success: true };
|
|
65088
|
-
delete templates[input.id];
|
|
65089
|
-
await this.templatesState.set(templates);
|
|
65090
|
-
this.deps.logger.info("template deleted", { meta: { templateId: input.id } });
|
|
65091
|
-
return { success: true };
|
|
65092
|
-
}
|
|
65093
64626
|
catalogCache = /* @__PURE__ */ new Map();
|
|
65094
64627
|
/**
|
|
65095
64628
|
* A node's `PipelineSchema`: the cached answer when fresh, else ONE live
|
|
@@ -65651,21 +65184,6 @@ var PipelineSettingsStore = class PipelineSettingsStore {
|
|
|
65651
65184
|
const v = value;
|
|
65652
65185
|
return Array.isArray(v["steps"]);
|
|
65653
65186
|
}
|
|
65654
|
-
isPipelineTemplate(value) {
|
|
65655
|
-
if (!value || typeof value !== "object") return false;
|
|
65656
|
-
const v = value;
|
|
65657
|
-
return typeof v["id"] === "string" && typeof v["name"] === "string" && typeof v["createdAt"] === "string" && typeof v["updatedAt"] === "string" && this.isCameraPipelineConfig(v["config"]);
|
|
65658
|
-
}
|
|
65659
|
-
/**
|
|
65660
|
-
* Generate a short template id. Collision risk at N≤1000 templates is
|
|
65661
|
-
* effectively zero (12 hex chars = 48 bits of entropy). Not a UUID
|
|
65662
|
-
* because the persisted shape is a plain map keyed by id and shorter
|
|
65663
|
-
* keys keep the JSON compact.
|
|
65664
|
-
*/
|
|
65665
|
-
generateTemplateId() {
|
|
65666
|
-
const rand = Math.random().toString(36).slice(2, 8);
|
|
65667
|
-
return `tpl_${Date.now().toString(36).slice(-6)}${rand}`;
|
|
65668
|
-
}
|
|
65669
65187
|
};
|
|
65670
65188
|
/**
|
|
65671
65189
|
* The camera's override for one accelerator, with its CAMERA-WIDE settings
|
|
@@ -69314,6 +68832,10 @@ async function buildOrchestratorControllers(deps) {
|
|
|
69314
68832
|
onCensus: (entries) => {
|
|
69315
68833
|
motionSliceGate?.noteCensus(entries);
|
|
69316
68834
|
providerSliceGate?.refreshIfStale("runner-census");
|
|
68835
|
+
},
|
|
68836
|
+
eligibleDeviceKeys: async (nodeId) => {
|
|
68837
|
+
const read = await deps.getEligibleInferenceDevicesIfCached(nodeId);
|
|
68838
|
+
return read.kind === "eligible" ? Object.keys(read.eligible) : null;
|
|
69317
68839
|
}
|
|
69318
68840
|
});
|
|
69319
68841
|
/**
|
|
@@ -70172,12 +69694,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
70172
69694
|
id: CLUSTER_MODEL_SECTION_ID,
|
|
70173
69695
|
title: "Enrichment models",
|
|
70174
69696
|
tab: "pipeline",
|
|
70175
|
-
description: "The
|
|
69697
|
+
description: "The face and search encoders, one each for the whole cluster: each fills a single shared index, and vectors from two models cannot be compared. Changing one keeps what is stored but hides it from matching and search until it is re-embedded.",
|
|
70176
69698
|
fields: [...CLUSTER_MODEL_SCOPED_STEPS.map((step) => ({
|
|
70177
69699
|
key: clusterModelSettingKey(step.stepId),
|
|
70178
69700
|
type: "select",
|
|
70179
69701
|
label: step.label,
|
|
70180
|
-
description: `
|
|
69702
|
+
description: `Used on every node. A node that has no build of this model skips the step (and logs it) rather than use another model. Changing it hides what is already in ${step.indexName} until it is re-embedded.`,
|
|
70181
69703
|
options: step.options.map((o) => ({
|
|
70182
69704
|
value: o.id,
|
|
70183
69705
|
label: o.label
|
|
@@ -70199,12 +69721,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
70199
69721
|
id: DETAIL_CROP_SECTION_ID,
|
|
70200
69722
|
title: "Enrichment crop",
|
|
70201
69723
|
tab: "pipeline",
|
|
70202
|
-
description: "How the crop
|
|
69724
|
+
description: "How the crop handed to the search, face and plate models is cut from the frame. One value for the whole cluster, because search results are only comparable when every crop is cut the same way. After changing it, rebuild the search index (Camera → Semantic search index → Rebuild).",
|
|
70203
69725
|
fields: [{
|
|
70204
69726
|
key: DETAIL_CROP_PADDING_KEY,
|
|
70205
69727
|
type: "slider",
|
|
70206
69728
|
label: "Crop margin",
|
|
70207
|
-
description: "
|
|
69729
|
+
description: "Extra margin added on each side of the detection box, as a fraction of its size. 0 = tight box, 0.15 = default. Search works better with some surroundings in the crop.",
|
|
70208
69730
|
min: DETAIL_CROP_PADDING_FIELD.min,
|
|
70209
69731
|
max: DETAIL_CROP_PADDING_FIELD.max,
|
|
70210
69732
|
step: DETAIL_CROP_PADDING_FIELD.step,
|
|
@@ -70214,7 +69736,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70214
69736
|
key: DETAIL_CROP_SQUARE_KEY,
|
|
70215
69737
|
type: "boolean",
|
|
70216
69738
|
label: "Square the crop",
|
|
70217
|
-
description: "
|
|
69739
|
+
description: "Widen the crop to a square so a tall subject is not squashed when the model resizes it. Off by default because the existing index was built without it.",
|
|
70218
69740
|
default: DEFAULT_DETAIL_CROP_CONVENTION.square
|
|
70219
69741
|
}]
|
|
70220
69742
|
},
|
|
@@ -70222,13 +69744,13 @@ function buildGlobalSettingsSections(options) {
|
|
|
70222
69744
|
id: NATIVE_LEASE_SECTION_ID,
|
|
70223
69745
|
title: "Native frame lease",
|
|
70224
69746
|
tab: "pipeline",
|
|
70225
|
-
description: "How
|
|
69747
|
+
description: "How each camera keeps full-resolution pixels so a crop taken seconds later (snapshot, face, plate) is sharp instead of cut from the small detection frame. A held frame is a whole picture (~25 MB at 4K) kept until its detections arrive; a tile is one subject, or one whole-scene copy, saved as JPEG for tens of seconds. Applies from the next session of each camera.",
|
|
70226
69748
|
fields: [
|
|
70227
69749
|
{
|
|
70228
69750
|
key: NATIVE_LEASE_HOLD_KEY,
|
|
70229
69751
|
type: "slider",
|
|
70230
69752
|
label: "Frames held at once",
|
|
70231
|
-
description: "
|
|
69753
|
+
description: "Most frames kept per camera while their detections are pending; past it the oldest is dropped. 1 to 4 are in use normally. Raise it only if a slow node drops frames (holdOverflow in the logs) — it does not make crops sharper.",
|
|
70232
69754
|
min: NATIVE_LEASE_HOLD_FIELD.min,
|
|
70233
69755
|
max: NATIVE_LEASE_HOLD_FIELD.max,
|
|
70234
69756
|
step: NATIVE_LEASE_HOLD_FIELD.step,
|
|
@@ -70240,7 +69762,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70240
69762
|
key: NATIVE_LEASE_TILE_BUDGET_KEY,
|
|
70241
69763
|
type: "slider",
|
|
70242
69764
|
label: "Subject tile RAM",
|
|
70243
|
-
description: "RAM per
|
|
69765
|
+
description: "RAM per camera for subject tiles: full-resolution crops of each detected subject, kept so a crop asked for seconds later is still sharp. A tile is ~60-120 KB. 0 = off (late crops come from the small detection frame).",
|
|
70244
69766
|
min: NATIVE_LEASE_TILE_BUDGET_FIELD.min,
|
|
70245
69767
|
max: NATIVE_LEASE_TILE_BUDGET_FIELD.max,
|
|
70246
69768
|
step: NATIVE_LEASE_TILE_BUDGET_FIELD.step,
|
|
@@ -70252,7 +69774,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70252
69774
|
key: NATIVE_LEASE_SCENE_BUDGET_KEY,
|
|
70253
69775
|
type: "slider",
|
|
70254
69776
|
label: "Scene tile RAM",
|
|
70255
|
-
description: "RAM per
|
|
69777
|
+
description: "RAM per camera for scene tiles: a full-resolution JPEG of the whole picture (~2 MB at 4K) on frames where something was detected, for key frames and whole-frame crops. 0 = off (those then fall back to the small detection frame).",
|
|
70256
69778
|
min: NATIVE_LEASE_SCENE_BUDGET_FIELD.min,
|
|
70257
69779
|
max: NATIVE_LEASE_SCENE_BUDGET_FIELD.max,
|
|
70258
69780
|
step: NATIVE_LEASE_SCENE_BUDGET_FIELD.step,
|
|
@@ -70264,7 +69786,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70264
69786
|
key: NATIVE_LEASE_BUDGET_KEY,
|
|
70265
69787
|
type: "slider",
|
|
70266
69788
|
label: "Lease RAM ceiling",
|
|
70267
|
-
description: "
|
|
69789
|
+
description: "Safety ceiling on the RAM held frames may use per camera; the frame count above is what normally limits it. Lower it on a small host. 0 turns full-resolution crops off almost entirely — for diagnosis only.",
|
|
70268
69790
|
min: NATIVE_LEASE_BUDGET_FIELD.min,
|
|
70269
69791
|
max: NATIVE_LEASE_BUDGET_FIELD.max,
|
|
70270
69792
|
step: NATIVE_LEASE_BUDGET_FIELD.step,
|
|
@@ -70276,7 +69798,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70276
69798
|
key: NATIVE_LEASE_ACTIVITY_KEY,
|
|
70277
69799
|
type: "slider",
|
|
70278
69800
|
label: "Demand window",
|
|
70279
|
-
description: "
|
|
69801
|
+
description: "Keep full-resolution pixels only within this long of the last crop request, so a camera nobody crops costs nothing; the first crop after a quiet spell falls back once. 0 = always keep (heavy on small hosts).",
|
|
70280
69802
|
min: NATIVE_LEASE_ACTIVITY_FIELD.min,
|
|
70281
69803
|
max: NATIVE_LEASE_ACTIVITY_FIELD.max,
|
|
70282
69804
|
step: NATIVE_LEASE_ACTIVITY_FIELD.step,
|
|
@@ -70289,7 +69811,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70289
69811
|
key: NATIVE_LEASE_ADMISSION_KEY,
|
|
70290
69812
|
type: "select",
|
|
70291
69813
|
label: "What to retain",
|
|
70292
|
-
description: "
|
|
69814
|
+
description: "Which frames get a full-resolution copy. 'Only frames sent to inference' keeps the frames a crop can actually ask for (about 80% less RAM); 'Every delivered frame' keeps all of them.",
|
|
70293
69815
|
options: NATIVE_LEASE_ADMISSION_FIELD.options,
|
|
70294
69816
|
default: NATIVE_LEASE_ADMISSION_FIELD.default
|
|
70295
69817
|
}
|
|
@@ -70302,7 +69824,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70302
69824
|
{
|
|
70303
69825
|
key: "onDisconnect",
|
|
70304
69826
|
type: "select",
|
|
70305
|
-
label: "
|
|
69827
|
+
label: "When a node disconnects",
|
|
69828
|
+
description: "Move its unpinned cameras to other nodes, or leave them stopped.",
|
|
70306
69829
|
default: DEFAULT_FAILOVER_POLICY.onDisconnect,
|
|
70307
69830
|
options: [{
|
|
70308
69831
|
value: "migrate",
|
|
@@ -70315,7 +69838,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70315
69838
|
{
|
|
70316
69839
|
key: "pinnedOnDisconnect",
|
|
70317
69840
|
type: "select",
|
|
70318
|
-
label: "
|
|
69841
|
+
label: "Its pinned cameras",
|
|
69842
|
+
description: "Keep the pin and wait for the node, or drop the pin and move them.",
|
|
70319
69843
|
default: DEFAULT_FAILOVER_POLICY.pinnedOnDisconnect,
|
|
70320
69844
|
options: [{
|
|
70321
69845
|
value: "leave-pinned",
|
|
@@ -70328,7 +69852,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70328
69852
|
{
|
|
70329
69853
|
key: "onReconnect",
|
|
70330
69854
|
type: "select",
|
|
70331
|
-
label: "
|
|
69855
|
+
label: "When it comes back",
|
|
69856
|
+
description: "Put its cameras back where they were, or rebalance the whole cluster.",
|
|
70332
69857
|
default: DEFAULT_FAILOVER_POLICY.onReconnect,
|
|
70333
69858
|
options: [{
|
|
70334
69859
|
value: "restore",
|
|
@@ -71825,7 +71350,7 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
71825
71350
|
nodeLifecycle = null;
|
|
71826
71351
|
/**
|
|
71827
71352
|
* The 3-level pipeline settings store (agent + camera settings maps,
|
|
71828
|
-
*
|
|
71353
|
+
* pipeline-executor catalog cache) plus the co-declared
|
|
71829
71354
|
* `nodeBindings` capability-binding map and the one-shot bindings-
|
|
71830
71355
|
* migration guard flag — see `pipeline-settings-store.ts` (S4
|
|
71831
71356
|
* extraction, cluster C11). Constructed early in `onInitialize` (before
|
|
@@ -72329,7 +71854,7 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
72329
71854
|
async getAgentLoad() {
|
|
72330
71855
|
await this.loadService.refreshDecodeHwaccels();
|
|
72331
71856
|
await this.loadService.collectAgentLoad();
|
|
72332
|
-
return this.loadService.
|
|
71857
|
+
return this.loadService.reportedAgentLoad();
|
|
72333
71858
|
}
|
|
72334
71859
|
async getGlobalMetrics() {
|
|
72335
71860
|
const summaries = await this.getAgentLoad();
|
|
@@ -73387,18 +72912,6 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
73387
72912
|
const resolved = await this.settingsStore.resolvePipelineForDevice(deviceId);
|
|
73388
72913
|
this.emitCameraUpdated(deviceId, resolved);
|
|
73389
72914
|
}
|
|
73390
|
-
async listTemplates() {
|
|
73391
|
-
return this.settingsStore.listTemplates();
|
|
73392
|
-
}
|
|
73393
|
-
async saveTemplate(input) {
|
|
73394
|
-
return this.settingsStore.saveTemplate(input);
|
|
73395
|
-
}
|
|
73396
|
-
async updateTemplate(input) {
|
|
73397
|
-
return this.settingsStore.updateTemplate(input);
|
|
73398
|
-
}
|
|
73399
|
-
async deleteTemplate(input) {
|
|
73400
|
-
return this.settingsStore.deleteTemplate(input);
|
|
73401
|
-
}
|
|
73402
72915
|
/**
|
|
73403
72916
|
* The per-camera FUNCTION SWITCH group (D61) — derived, never stored.
|
|
73404
72917
|
*
|