@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.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,
|
|
@@ -24428,21 +24223,6 @@ var PipelineDefaultStepSchema = lazy(() => object({
|
|
|
24428
24223
|
group: string().optional(),
|
|
24429
24224
|
settings: record(string(), unknown()).optional()
|
|
24430
24225
|
}));
|
|
24431
|
-
var PipelineTemplateStepSchema = lazy(() => object({
|
|
24432
|
-
addonId: string(),
|
|
24433
|
-
enabled: boolean(),
|
|
24434
|
-
modelId: string(),
|
|
24435
|
-
children: array(PipelineTemplateStepSchema).readonly(),
|
|
24436
|
-
settings: record(string(), unknown()).optional()
|
|
24437
|
-
}));
|
|
24438
|
-
var PipelineTemplateSchema$1 = object({
|
|
24439
|
-
id: string(),
|
|
24440
|
-
name: string(),
|
|
24441
|
-
createdAt: string(),
|
|
24442
|
-
updatedAt: string(),
|
|
24443
|
-
engine: PipelineEngineChoiceSchema,
|
|
24444
|
-
steps: array(PipelineTemplateStepSchema).readonly()
|
|
24445
|
-
});
|
|
24446
24226
|
var PipelineModelOptionSchema = object({
|
|
24447
24227
|
id: string(),
|
|
24448
24228
|
name: string(),
|
|
@@ -24764,18 +24544,6 @@ var pipelineExecutorCapability = {
|
|
|
24764
24544
|
steps: array(PipelineStepInputSchema),
|
|
24765
24545
|
deviceKey: string().optional()
|
|
24766
24546
|
}), PipelineValidationResultSchema),
|
|
24767
|
-
listTemplates: method(_void(), array(PipelineTemplateSchema$1).readonly()),
|
|
24768
|
-
saveTemplate: method(object({
|
|
24769
|
-
name: string(),
|
|
24770
|
-
steps: array(PipelineTemplateStepSchema).readonly(),
|
|
24771
|
-
engine: PipelineEngineChoiceSchema
|
|
24772
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
24773
|
-
updateTemplate: method(object({
|
|
24774
|
-
id: string(),
|
|
24775
|
-
name: string().optional(),
|
|
24776
|
-
steps: array(PipelineTemplateStepSchema).readonly().optional()
|
|
24777
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }),
|
|
24778
|
-
deleteTemplate: method(object({ id: string() }), _void(), { kind: "mutation" }),
|
|
24779
24547
|
getCapabilities: method(_void(), InferenceCapabilitiesBridge),
|
|
24780
24548
|
getAddonModels: method(object({ addonId: string() }), ModelAvailabilityListBridge),
|
|
24781
24549
|
downloadModel: method(object({
|
|
@@ -26535,14 +26303,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
26535
26303
|
* Per-inference-device live load (multi-device C4). One entry per deviceKey
|
|
26536
26304
|
* this runner currently has attached cameras on, so the orchestrator's second
|
|
26537
26305
|
* `balance()` pass (over a node's devices) weights on real per-pool session
|
|
26538
|
-
* counts. Empty on single-device / pre-multi-device runners.
|
|
26539
|
-
* 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).
|
|
26540
26310
|
*/
|
|
26541
26311
|
devices: array(object({
|
|
26542
26312
|
deviceKey: string(),
|
|
26543
26313
|
backend: string(),
|
|
26544
|
-
attachedCameras: number()
|
|
26545
|
-
queueDepthTotal: number()
|
|
26314
|
+
attachedCameras: number()
|
|
26546
26315
|
})).default([]),
|
|
26547
26316
|
/** Hardware capability flags reported by this node. */
|
|
26548
26317
|
hardware: object({
|
|
@@ -26756,14 +26525,6 @@ var CameraPipelineConfigSchema = object({
|
|
|
26756
26525
|
settings: record(string(), unknown()).readonly().optional()
|
|
26757
26526
|
}).nullable().optional()
|
|
26758
26527
|
});
|
|
26759
|
-
var PipelineTemplateSchema = object({
|
|
26760
|
-
id: string(),
|
|
26761
|
-
name: string(),
|
|
26762
|
-
description: string().optional(),
|
|
26763
|
-
config: CameraPipelineConfigSchema,
|
|
26764
|
-
createdAt: string(),
|
|
26765
|
-
updatedAt: string()
|
|
26766
|
-
});
|
|
26767
26528
|
var DeviceStepConfigSchema = object({
|
|
26768
26529
|
modelId: string().optional(),
|
|
26769
26530
|
settings: record(string(), unknown()).optional(),
|
|
@@ -26873,7 +26634,10 @@ var PipelineAssignmentSchema = object({
|
|
|
26873
26634
|
});
|
|
26874
26635
|
/**
|
|
26875
26636
|
* Per-agent load summary surfaced to the load balancer + dashboards.
|
|
26876
|
-
* 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.
|
|
26877
26641
|
*/
|
|
26878
26642
|
var AgentLoadSummarySchema = object({
|
|
26879
26643
|
nodeId: string(),
|
|
@@ -26962,26 +26726,27 @@ var CameraBrokerStatusSchema = object({
|
|
|
26962
26726
|
width: number(),
|
|
26963
26727
|
height: number(),
|
|
26964
26728
|
subscribers: number(),
|
|
26965
|
-
|
|
26966
|
-
|
|
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()
|
|
26967
26737
|
})).readonly(),
|
|
26968
26738
|
webrtcSessions: number(),
|
|
26969
26739
|
rtspRestream: boolean()
|
|
26970
26740
|
});
|
|
26971
|
-
/**
|
|
26972
|
-
|
|
26973
|
-
|
|
26974
|
-
|
|
26975
|
-
|
|
26976
|
-
|
|
26977
|
-
|
|
26978
|
-
|
|
26979
|
-
var CameraDecoderStatusSchema = object({
|
|
26980
|
-
nodeId: string(),
|
|
26981
|
-
formats: array(string()).readonly(),
|
|
26982
|
-
sessionCount: number(),
|
|
26983
|
-
shm: CameraDecoderShmSchema
|
|
26984
|
-
});
|
|
26741
|
+
/**
|
|
26742
|
+
* Decoder block — WHERE decode runs (co-located with the detection node by
|
|
26743
|
+
* construction); null when the camera has no detection node. It carries no
|
|
26744
|
+
* frame counter: the shared-memory plane whose counters it used to serve is
|
|
26745
|
+
* gone, and those fields read 0 forever. Whether frames actually flow is read
|
|
26746
|
+
* from `detection.actualFps` (frames delivered to and processed by the
|
|
26747
|
+
* detector), never from a counter nothing feeds.
|
|
26748
|
+
*/
|
|
26749
|
+
var CameraDecoderStatusSchema = object({ nodeId: string() });
|
|
26985
26750
|
/** Motion block — null when motion detection is not active for this device. */
|
|
26986
26751
|
var CameraMotionStatusSchema = object({
|
|
26987
26752
|
enabled: boolean(),
|
|
@@ -27835,33 +27600,7 @@ var pipelineOrchestratorCapability = {
|
|
|
27835
27600
|
auth: "admin"
|
|
27836
27601
|
}),
|
|
27837
27602
|
/** Snapshot of the in-flight or last disk-wins fleet reconcile. */
|
|
27838
|
-
getReconcileFromDiskStatus: method(_void(), DiskReconcileJobSchema, { auth: "admin" })
|
|
27839
|
-
/** List every template the operator has saved. */
|
|
27840
|
-
listTemplates: method(_void(), array(PipelineTemplateSchema).readonly()),
|
|
27841
|
-
/** Create a new named preset from a given CameraPipelineConfig. */
|
|
27842
|
-
saveTemplate: method(object({
|
|
27843
|
-
name: string(),
|
|
27844
|
-
description: string().optional(),
|
|
27845
|
-
config: CameraPipelineConfigSchema
|
|
27846
|
-
}), PipelineTemplateSchema, {
|
|
27847
|
-
kind: "mutation",
|
|
27848
|
-
auth: "admin"
|
|
27849
|
-
}),
|
|
27850
|
-
/** Partial update of a template. Any omitted field is preserved. */
|
|
27851
|
-
updateTemplate: method(object({
|
|
27852
|
-
id: string(),
|
|
27853
|
-
name: string().optional(),
|
|
27854
|
-
description: string().optional(),
|
|
27855
|
-
config: CameraPipelineConfigSchema.optional()
|
|
27856
|
-
}), PipelineTemplateSchema, {
|
|
27857
|
-
kind: "mutation",
|
|
27858
|
-
auth: "admin"
|
|
27859
|
-
}),
|
|
27860
|
-
/** Remove a template. Camera configs that were seeded from it keep a copy. */
|
|
27861
|
-
deleteTemplate: method(object({ id: string() }), object({ success: literal(true) }), {
|
|
27862
|
-
kind: "mutation",
|
|
27863
|
-
auth: "admin"
|
|
27864
|
-
})
|
|
27603
|
+
getReconcileFromDiskStatus: method(_void(), DiskReconcileJobSchema, { auth: "admin" })
|
|
27865
27604
|
}
|
|
27866
27605
|
};
|
|
27867
27606
|
/**
|
|
@@ -30083,8 +29822,6 @@ var WebrtcStreamChoiceSchema = object({
|
|
|
30083
29822
|
]).nullable(),
|
|
30084
29823
|
/** Input FPS from the camera (null for adaptive). */
|
|
30085
29824
|
inputFps: number().nullable(),
|
|
30086
|
-
/** Decoded FPS (null for adaptive). */
|
|
30087
|
-
decodeFps: number().nullable(),
|
|
30088
29825
|
/** Bitrate in kbps (null for adaptive). */
|
|
30089
29826
|
bitrateKbps: number().nullable()
|
|
30090
29827
|
});
|
|
@@ -40330,90 +40067,18 @@ Object.freeze({
|
|
|
40330
40067
|
addonId: null,
|
|
40331
40068
|
access: "create"
|
|
40332
40069
|
},
|
|
40333
|
-
"decoder.createSession": {
|
|
40334
|
-
capName: "decoder",
|
|
40335
|
-
capScope: "system",
|
|
40336
|
-
addonId: null,
|
|
40337
|
-
access: "view"
|
|
40338
|
-
},
|
|
40339
|
-
"decoder.destroySession": {
|
|
40340
|
-
capName: "decoder",
|
|
40341
|
-
capScope: "system",
|
|
40342
|
-
addonId: null,
|
|
40343
|
-
access: "delete"
|
|
40344
|
-
},
|
|
40345
|
-
"decoder.getFrame": {
|
|
40346
|
-
capName: "decoder",
|
|
40347
|
-
capScope: "system",
|
|
40348
|
-
addonId: null,
|
|
40349
|
-
access: "view"
|
|
40350
|
-
},
|
|
40351
40070
|
"decoder.getInfo": {
|
|
40352
40071
|
capName: "decoder",
|
|
40353
40072
|
capScope: "system",
|
|
40354
40073
|
addonId: null,
|
|
40355
40074
|
access: "view"
|
|
40356
40075
|
},
|
|
40357
|
-
"decoder.getShmStats": {
|
|
40358
|
-
capName: "decoder",
|
|
40359
|
-
capScope: "system",
|
|
40360
|
-
addonId: null,
|
|
40361
|
-
access: "view"
|
|
40362
|
-
},
|
|
40363
|
-
"decoder.getStats": {
|
|
40364
|
-
capName: "decoder",
|
|
40365
|
-
capScope: "system",
|
|
40366
|
-
addonId: null,
|
|
40367
|
-
access: "view"
|
|
40368
|
-
},
|
|
40369
|
-
"decoder.listActiveSessions": {
|
|
40370
|
-
capName: "decoder",
|
|
40371
|
-
capScope: "system",
|
|
40372
|
-
addonId: null,
|
|
40373
|
-
access: "view"
|
|
40374
|
-
},
|
|
40375
|
-
"decoder.openStream": {
|
|
40376
|
-
capName: "decoder",
|
|
40377
|
-
capScope: "system",
|
|
40378
|
-
addonId: null,
|
|
40379
|
-
access: "view"
|
|
40380
|
-
},
|
|
40381
|
-
"decoder.pullFrames": {
|
|
40382
|
-
capName: "decoder",
|
|
40383
|
-
capScope: "system",
|
|
40384
|
-
addonId: null,
|
|
40385
|
-
access: "view"
|
|
40386
|
-
},
|
|
40387
|
-
"decoder.pullHandles": {
|
|
40388
|
-
capName: "decoder",
|
|
40389
|
-
capScope: "system",
|
|
40390
|
-
addonId: null,
|
|
40391
|
-
access: "view"
|
|
40392
|
-
},
|
|
40393
|
-
"decoder.pushPacket": {
|
|
40394
|
-
capName: "decoder",
|
|
40395
|
-
capScope: "system",
|
|
40396
|
-
addonId: null,
|
|
40397
|
-
access: "view"
|
|
40398
|
-
},
|
|
40399
40076
|
"decoder.reprobeHwaccel": {
|
|
40400
40077
|
capName: "decoder",
|
|
40401
40078
|
capScope: "system",
|
|
40402
40079
|
addonId: null,
|
|
40403
40080
|
access: "create"
|
|
40404
40081
|
},
|
|
40405
|
-
"decoder.supportsCodec": {
|
|
40406
|
-
capName: "decoder",
|
|
40407
|
-
capScope: "system",
|
|
40408
|
-
addonId: null,
|
|
40409
|
-
access: "view"
|
|
40410
|
-
},
|
|
40411
|
-
"decoder.updateConfig": {
|
|
40412
|
-
capName: "decoder",
|
|
40413
|
-
capScope: "system",
|
|
40414
|
-
addonId: null,
|
|
40415
|
-
access: "view"
|
|
40416
|
-
},
|
|
40417
40082
|
"detectionPipeline.applyDeviceSettingsPatch": {
|
|
40418
40083
|
capName: "detection-pipeline",
|
|
40419
40084
|
capScope: "device",
|
|
@@ -43504,12 +43169,6 @@ Object.freeze({
|
|
|
43504
43169
|
addonId: null,
|
|
43505
43170
|
access: "delete"
|
|
43506
43171
|
},
|
|
43507
|
-
"pipelineExecutor.deleteTemplate": {
|
|
43508
|
-
capName: "pipeline-executor",
|
|
43509
|
-
capScope: "system",
|
|
43510
|
-
addonId: null,
|
|
43511
|
-
access: "delete"
|
|
43512
|
-
},
|
|
43513
43172
|
"pipelineExecutor.downloadModel": {
|
|
43514
43173
|
capName: "pipeline-executor",
|
|
43515
43174
|
capScope: "system",
|
|
@@ -43648,12 +43307,6 @@ Object.freeze({
|
|
|
43648
43307
|
addonId: null,
|
|
43649
43308
|
access: "view"
|
|
43650
43309
|
},
|
|
43651
|
-
"pipelineExecutor.listTemplates": {
|
|
43652
|
-
capName: "pipeline-executor",
|
|
43653
|
-
capScope: "system",
|
|
43654
|
-
addonId: null,
|
|
43655
|
-
access: "view"
|
|
43656
|
-
},
|
|
43657
43310
|
"pipelineExecutor.rearmInferenceDevice": {
|
|
43658
43311
|
capName: "pipeline-executor",
|
|
43659
43312
|
capScope: "system",
|
|
@@ -43678,12 +43331,6 @@ Object.freeze({
|
|
|
43678
43331
|
addonId: null,
|
|
43679
43332
|
access: "create"
|
|
43680
43333
|
},
|
|
43681
|
-
"pipelineExecutor.saveTemplate": {
|
|
43682
|
-
capName: "pipeline-executor",
|
|
43683
|
-
capScope: "system",
|
|
43684
|
-
addonId: null,
|
|
43685
|
-
access: "create"
|
|
43686
|
-
},
|
|
43687
43334
|
"pipelineExecutor.setVideoPipelineSteps": {
|
|
43688
43335
|
capName: "pipeline-executor",
|
|
43689
43336
|
capScope: "system",
|
|
@@ -43702,12 +43349,6 @@ Object.freeze({
|
|
|
43702
43349
|
addonId: null,
|
|
43703
43350
|
access: "create"
|
|
43704
43351
|
},
|
|
43705
|
-
"pipelineExecutor.updateTemplate": {
|
|
43706
|
-
capName: "pipeline-executor",
|
|
43707
|
-
capScope: "system",
|
|
43708
|
-
addonId: null,
|
|
43709
|
-
access: "create"
|
|
43710
|
-
},
|
|
43711
43352
|
"pipelineExecutor.validatePipeline": {
|
|
43712
43353
|
capName: "pipeline-executor",
|
|
43713
43354
|
capScope: "system",
|
|
@@ -43738,12 +43379,6 @@ Object.freeze({
|
|
|
43738
43379
|
addonId: null,
|
|
43739
43380
|
access: "create"
|
|
43740
43381
|
},
|
|
43741
|
-
"pipelineOrchestrator.deleteTemplate": {
|
|
43742
|
-
capName: "pipeline-orchestrator",
|
|
43743
|
-
capScope: "system",
|
|
43744
|
-
addonId: null,
|
|
43745
|
-
access: "delete"
|
|
43746
|
-
},
|
|
43747
43382
|
"pipelineOrchestrator.getAgentLoad": {
|
|
43748
43383
|
capName: "pipeline-orchestrator",
|
|
43749
43384
|
capScope: "system",
|
|
@@ -43894,12 +43529,6 @@ Object.freeze({
|
|
|
43894
43529
|
addonId: null,
|
|
43895
43530
|
access: "view"
|
|
43896
43531
|
},
|
|
43897
|
-
"pipelineOrchestrator.listTemplates": {
|
|
43898
|
-
capName: "pipeline-orchestrator",
|
|
43899
|
-
capScope: "system",
|
|
43900
|
-
addonId: null,
|
|
43901
|
-
access: "view"
|
|
43902
|
-
},
|
|
43903
43532
|
"pipelineOrchestrator.pauseForStorageMigration": {
|
|
43904
43533
|
capName: "pipeline-orchestrator",
|
|
43905
43534
|
capScope: "system",
|
|
@@ -43954,12 +43583,6 @@ Object.freeze({
|
|
|
43954
43583
|
addonId: null,
|
|
43955
43584
|
access: "create"
|
|
43956
43585
|
},
|
|
43957
|
-
"pipelineOrchestrator.saveTemplate": {
|
|
43958
|
-
capName: "pipeline-orchestrator",
|
|
43959
|
-
capScope: "system",
|
|
43960
|
-
addonId: null,
|
|
43961
|
-
access: "create"
|
|
43962
|
-
},
|
|
43963
43586
|
"pipelineOrchestrator.setAgentCapabilities": {
|
|
43964
43587
|
capName: "pipeline-orchestrator",
|
|
43965
43588
|
capScope: "system",
|
|
@@ -44068,12 +43691,6 @@ Object.freeze({
|
|
|
44068
43691
|
addonId: null,
|
|
44069
43692
|
access: "create"
|
|
44070
43693
|
},
|
|
44071
|
-
"pipelineOrchestrator.updateTemplate": {
|
|
44072
|
-
capName: "pipeline-orchestrator",
|
|
44073
|
-
capScope: "system",
|
|
44074
|
-
addonId: null,
|
|
44075
|
-
access: "create"
|
|
44076
|
-
},
|
|
44077
43694
|
"pipelineRunner.attachCamera": {
|
|
44078
43695
|
capName: "pipeline-runner",
|
|
44079
43696
|
capScope: "system",
|
|
@@ -45508,12 +45125,6 @@ Object.freeze({
|
|
|
45508
45125
|
addonId: null,
|
|
45509
45126
|
access: "view"
|
|
45510
45127
|
},
|
|
45511
|
-
"streamBroker.pullFrameHandles": {
|
|
45512
|
-
capName: "stream-broker",
|
|
45513
|
-
capScope: "system",
|
|
45514
|
-
addonId: null,
|
|
45515
|
-
access: "view"
|
|
45516
|
-
},
|
|
45517
45128
|
"streamBroker.regenerateRtspToken": {
|
|
45518
45129
|
capName: "stream-broker",
|
|
45519
45130
|
capScope: "system",
|
|
@@ -45580,12 +45191,6 @@ Object.freeze({
|
|
|
45580
45191
|
addonId: null,
|
|
45581
45192
|
access: "create"
|
|
45582
45193
|
},
|
|
45583
|
-
"streamBroker.subscribeFrames": {
|
|
45584
|
-
capName: "stream-broker",
|
|
45585
|
-
capScope: "system",
|
|
45586
|
-
addonId: null,
|
|
45587
|
-
access: "create"
|
|
45588
|
-
},
|
|
45589
45194
|
"streamBroker.unassignProfile": {
|
|
45590
45195
|
capName: "stream-broker",
|
|
45591
45196
|
capScope: "system",
|
|
@@ -45598,12 +45203,6 @@ Object.freeze({
|
|
|
45598
45203
|
addonId: null,
|
|
45599
45204
|
access: "create"
|
|
45600
45205
|
},
|
|
45601
|
-
"streamBroker.unsubscribeFrames": {
|
|
45602
|
-
capName: "stream-broker",
|
|
45603
|
-
capScope: "system",
|
|
45604
|
-
addonId: null,
|
|
45605
|
-
access: "create"
|
|
45606
|
-
},
|
|
45607
45206
|
"streamCatalog.getCatalog": {
|
|
45608
45207
|
capName: "stream-catalog",
|
|
45609
45208
|
capScope: "device",
|
|
@@ -48145,11 +47744,6 @@ Object.freeze({
|
|
|
48145
47744
|
form: "single",
|
|
48146
47745
|
optional: false
|
|
48147
47746
|
}],
|
|
48148
|
-
"decoder.createSession": [{
|
|
48149
|
-
name: "deviceId",
|
|
48150
|
-
form: "single",
|
|
48151
|
-
optional: true
|
|
48152
|
-
}],
|
|
48153
47747
|
"detectionPipeline.applyDeviceSettingsPatch": [{
|
|
48154
47748
|
name: "deviceId",
|
|
48155
47749
|
form: "single",
|
|
@@ -54866,6 +54460,40 @@ var LoadShedController = class LoadShedController {
|
|
|
54866
54460
|
}
|
|
54867
54461
|
};
|
|
54868
54462
|
//#endregion
|
|
54463
|
+
//#region src/default-pool-attribution.ts
|
|
54464
|
+
/** The backend prefix of a `<backend>:<device>` key (bare `cpu` → `cpu`). */
|
|
54465
|
+
function backendOf(deviceKey) {
|
|
54466
|
+
const colon = deviceKey.indexOf(":");
|
|
54467
|
+
return colon >= 0 ? deviceKey.slice(0, colon) : deviceKey;
|
|
54468
|
+
}
|
|
54469
|
+
/**
|
|
54470
|
+
* `load` with its unattributed sessions credited to `eligibleKeys[0]` when that
|
|
54471
|
+
* is the node's ONLY eligible device; `load` itself (same reference) otherwise.
|
|
54472
|
+
* `eligibleKeys` null = the eligible set is not known.
|
|
54473
|
+
*/
|
|
54474
|
+
function attributeDefaultPoolSessions(load, eligibleKeys) {
|
|
54475
|
+
if (eligibleKeys === null || eligibleKeys.length !== 1) return load;
|
|
54476
|
+
const onlyKey = eligibleKeys[0];
|
|
54477
|
+
if (onlyKey === void 0) return load;
|
|
54478
|
+
const attributed = load.devices.reduce((sum, d) => sum + d.attachedCameras, 0);
|
|
54479
|
+
const unattributed = load.attachedCameras - attributed;
|
|
54480
|
+
if (unattributed <= 0) return load;
|
|
54481
|
+
const existing = load.devices.find((d) => d.deviceKey === onlyKey);
|
|
54482
|
+
const credited = existing ? {
|
|
54483
|
+
...existing,
|
|
54484
|
+
attachedCameras: existing.attachedCameras + unattributed
|
|
54485
|
+
} : {
|
|
54486
|
+
deviceKey: onlyKey,
|
|
54487
|
+
backend: backendOf(onlyKey),
|
|
54488
|
+
attachedCameras: unattributed
|
|
54489
|
+
};
|
|
54490
|
+
const devices = [...load.devices.filter((d) => d.deviceKey !== onlyKey), credited].toSorted((a, b) => a.deviceKey.localeCompare(b.deviceKey));
|
|
54491
|
+
return {
|
|
54492
|
+
...load,
|
|
54493
|
+
devices
|
|
54494
|
+
};
|
|
54495
|
+
}
|
|
54496
|
+
//#endregion
|
|
54869
54497
|
//#region src/dispatch-timing.ts
|
|
54870
54498
|
/**
|
|
54871
54499
|
* How long the placement census waits for ONE runner's `getLocalCameras`
|
|
@@ -54932,6 +54560,25 @@ var AgentLoadService = class AgentLoadService {
|
|
|
54932
54560
|
getAgentLoadSummaries() {
|
|
54933
54561
|
return [...this.cachedAgentLoad.values()];
|
|
54934
54562
|
}
|
|
54563
|
+
/**
|
|
54564
|
+
* The cached summaries as the load REPORT (`getAgentLoad`) carries them: a
|
|
54565
|
+
* single-device node's default-pool sessions credited to its one device
|
|
54566
|
+
* (`default-pool-attribution.ts`). The balancer's census
|
|
54567
|
+
* ({@link collectAgentLoad}) stays the runner's raw answer.
|
|
54568
|
+
*/
|
|
54569
|
+
async reportedAgentLoad() {
|
|
54570
|
+
const resolve = this.deps.eligibleDeviceKeys;
|
|
54571
|
+
const summaries = this.getAgentLoadSummaries();
|
|
54572
|
+
if (resolve === void 0) return summaries;
|
|
54573
|
+
return Promise.all(summaries.map(async (summary) => {
|
|
54574
|
+
const eligible = await resolve(summary.nodeId).catch(() => null);
|
|
54575
|
+
const load = attributeDefaultPoolSessions(summary.load, eligible);
|
|
54576
|
+
return load === summary.load ? summary : {
|
|
54577
|
+
...summary,
|
|
54578
|
+
load
|
|
54579
|
+
};
|
|
54580
|
+
}));
|
|
54581
|
+
}
|
|
54935
54582
|
cachedAgentLoadNodeIds() {
|
|
54936
54583
|
return [...this.cachedAgentLoad.keys()];
|
|
54937
54584
|
}
|
|
@@ -57379,29 +57026,15 @@ function mapBroker(brokerResult) {
|
|
|
57379
57026
|
width: p.width,
|
|
57380
57027
|
height: p.height,
|
|
57381
57028
|
subscribers: p.subscribers,
|
|
57382
|
-
inFps: p.inFps
|
|
57383
|
-
outFps: p.outFps
|
|
57029
|
+
inFps: p.inFps
|
|
57384
57030
|
})),
|
|
57385
57031
|
webrtcSessions: brokerResult.webrtcSessions,
|
|
57386
57032
|
rtspRestream: brokerResult.rtspRestream
|
|
57387
57033
|
};
|
|
57388
57034
|
}
|
|
57389
|
-
function mapDecoderShm(shm) {
|
|
57390
|
-
return {
|
|
57391
|
-
framesWritten: shm.framesWritten,
|
|
57392
|
-
getFrameHits: shm.getFrameHits,
|
|
57393
|
-
getFrameMisses: shm.getFrameMisses,
|
|
57394
|
-
budgetMb: shm.budgetMb
|
|
57395
|
-
};
|
|
57396
|
-
}
|
|
57397
57035
|
function mapDecoder(decoderResult) {
|
|
57398
57036
|
if (decoderResult === null) return null;
|
|
57399
|
-
return {
|
|
57400
|
-
nodeId: decoderResult.nodeId,
|
|
57401
|
-
formats: [...decoderResult.formats],
|
|
57402
|
-
sessionCount: decoderResult.sessionCount,
|
|
57403
|
-
shm: mapDecoderShm(decoderResult.shm)
|
|
57404
|
-
};
|
|
57037
|
+
return { nodeId: decoderResult.nodeId };
|
|
57405
57038
|
}
|
|
57406
57039
|
function mapMotion(motionResult) {
|
|
57407
57040
|
if (motionResult === null) return null;
|
|
@@ -57780,11 +57413,9 @@ var CameraStatusService = class {
|
|
|
57780
57413
|
* `allSlotsFetch` (fetched once by the caller) to avoid a second
|
|
57781
57414
|
* round-trip. Per-slot `getBrokerStats` + `listClients` are fetched in
|
|
57782
57415
|
* parallel. WebRTC sessions are counted by filtering `encoded[]` entries
|
|
57783
|
-
* whose `attribution.kind` is one of the `WEBRTC_KINDS`.
|
|
57784
|
-
* broker's actual decode-session node into `liveDecoder` (T6) — the first
|
|
57785
|
-
* slot that reports one wins.
|
|
57416
|
+
* whose `attribution.kind` is one of the `WEBRTC_KINDS`.
|
|
57786
57417
|
*/
|
|
57787
|
-
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57418
|
+
buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, sink) {
|
|
57788
57419
|
if (!api || !allSlotsFetch) return Promise.resolve(null);
|
|
57789
57420
|
return this.boundedStage(allSlotsFetch.then(async (slots) => {
|
|
57790
57421
|
const deviceSlots = slots.filter((s) => s.deviceId === deviceId);
|
|
@@ -57801,19 +57432,16 @@ var CameraStatusService = class {
|
|
|
57801
57432
|
clients
|
|
57802
57433
|
};
|
|
57803
57434
|
})), pass.rtspEntries(api, sourceNodeId).catch(() => null)]);
|
|
57804
|
-
const profileDetails = statsAndClients.map(({ slot, stats, clients }) => ({
|
|
57805
|
-
profile: slot.profile,
|
|
57806
|
-
status: slot.status,
|
|
57807
|
-
codec: stats?.codec ?? slot.codec ?? "",
|
|
57808
|
-
width: slot.resolution?.width ?? 0,
|
|
57809
|
-
height: slot.resolution?.height ?? 0,
|
|
57810
|
-
subscribers: clients?.encodedSubscribers ?? 0,
|
|
57811
|
-
inFps: stats?.inputFps ?? 0,
|
|
57812
|
-
outFps: stats?.decodeFps ?? 0
|
|
57813
|
-
}));
|
|
57814
|
-
for (const { stats } of statsAndClients) if (liveDecoder.nodeId === null && typeof stats?.decoderNodeId === "string") liveDecoder.nodeId = stats.decoderNodeId;
|
|
57815
57435
|
return {
|
|
57816
|
-
profiles:
|
|
57436
|
+
profiles: statsAndClients.map(({ slot, stats, clients }) => ({
|
|
57437
|
+
profile: slot.profile,
|
|
57438
|
+
status: slot.status,
|
|
57439
|
+
codec: stats?.codec ?? slot.codec ?? "",
|
|
57440
|
+
width: slot.resolution?.width ?? 0,
|
|
57441
|
+
height: slot.resolution?.height ?? 0,
|
|
57442
|
+
subscribers: clients?.encodedSubscribers ?? 0,
|
|
57443
|
+
inFps: stats?.inputFps ?? null
|
|
57444
|
+
})),
|
|
57817
57445
|
webrtcSessions: statsAndClients.reduce((total, { clients }) => {
|
|
57818
57446
|
if (!clients) return total;
|
|
57819
57447
|
return total + clients.encoded.filter((c) => WEBRTC_KINDS.has(c.attribution.kind)).length;
|
|
@@ -57825,27 +57453,19 @@ var CameraStatusService = class {
|
|
|
57825
57453
|
}), STAGE_TIMEOUT_MS, "broker", deviceId, sink);
|
|
57826
57454
|
}
|
|
57827
57455
|
/**
|
|
57828
|
-
* Decoder stage
|
|
57829
|
-
*
|
|
57830
|
-
*
|
|
57831
|
-
*
|
|
57832
|
-
*
|
|
57833
|
-
*
|
|
57834
|
-
*
|
|
57835
|
-
*
|
|
57456
|
+
* Decoder stage: the node decode runs on BY CONSTRUCTION — the detection
|
|
57457
|
+
* node (decode is always co-located with its frame consumer). Unassigned
|
|
57458
|
+
* camera → null. (The ASSIGNMENT block upgrades to the broker's live session
|
|
57459
|
+
* node when observed — see the T6 post-processing in `getCameraStatus`.)
|
|
57460
|
+
*
|
|
57461
|
+
* No counter rides along. This block used to serve shared-memory ring stats,
|
|
57462
|
+
* session count and formats hard-coded to 0 / [] after the SHM frame plane
|
|
57463
|
+
* was retired (frames live in the in-RAM RetainedFrameStore), and the admin
|
|
57464
|
+
* UI raised "decode path stalled" on every active camera from those zeros.
|
|
57465
|
+
* Frames reaching the detector are read from `detection.actualFps`.
|
|
57836
57466
|
*/
|
|
57837
57467
|
buildDecoderStage(detectionNodeId) {
|
|
57838
|
-
return detectionNodeId ?
|
|
57839
|
-
nodeId: detectionNodeId,
|
|
57840
|
-
formats: [],
|
|
57841
|
-
sessionCount: 0,
|
|
57842
|
-
shm: {
|
|
57843
|
-
framesWritten: 0,
|
|
57844
|
-
getFrameHits: 0,
|
|
57845
|
-
getFrameMisses: 0,
|
|
57846
|
-
budgetMb: 0
|
|
57847
|
-
}
|
|
57848
|
-
}) : Promise.resolve(null);
|
|
57468
|
+
return Promise.resolve(detectionNodeId ? { nodeId: detectionNodeId } : null);
|
|
57849
57469
|
}
|
|
57850
57470
|
/**
|
|
57851
57471
|
* Motion stage (from cached runner config). Motion configuration lives in
|
|
@@ -58015,10 +57635,9 @@ var CameraStatusService = class {
|
|
|
58015
57635
|
const api = this.deps.api();
|
|
58016
57636
|
const degradations = { entries: [] };
|
|
58017
57637
|
const { detectionNodeId, sourceNodeId, pinned, detectionReason, audioNodeId, audioPinned } = this.buildAssignmentContext(deviceId);
|
|
58018
|
-
const liveDecoder = { nodeId: null };
|
|
58019
57638
|
const allSlotsFetch = api ? pass.profileSlots(api, sourceNodeId) : null;
|
|
58020
57639
|
const sourceFetch = this.buildSourceStage(api, allSlotsFetch, deviceId, degradations);
|
|
58021
|
-
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass,
|
|
57640
|
+
const brokerFetch = this.buildBrokerStage(api, allSlotsFetch, deviceId, sourceNodeId, pass, degradations);
|
|
58022
57641
|
const decoderFetch = this.buildDecoderStage(detectionNodeId);
|
|
58023
57642
|
const motionResult = this.buildMotionStage(deviceId);
|
|
58024
57643
|
const detectionFetch = this.buildDetectionStage(api, detectionNodeId, deviceId, pass, degradations);
|
|
@@ -58033,11 +57652,10 @@ var CameraStatusService = class {
|
|
|
58033
57652
|
switchesFetch
|
|
58034
57653
|
]);
|
|
58035
57654
|
const audioResult = this.buildAudioStage(audioNodeId, switchedOff);
|
|
58036
|
-
const
|
|
58037
|
-
const decoderNodeId = liveDecoderNodeId ?? detectionNodeId;
|
|
57655
|
+
const decoderNodeId = detectionNodeId;
|
|
58038
57656
|
const reasons = {
|
|
58039
57657
|
detection: detectionReason,
|
|
58040
|
-
decoder:
|
|
57658
|
+
decoder: decoderNodeId !== null ? "co-located" : void 0,
|
|
58041
57659
|
audio: audioPinned ? "manual" : void 0
|
|
58042
57660
|
};
|
|
58043
57661
|
return composeCameraStatus({
|
|
@@ -60274,7 +59892,7 @@ function deviceAsLoad(deviceKey, load) {
|
|
|
60274
59892
|
activeCameras: 0,
|
|
60275
59893
|
avgInferenceFps: 0,
|
|
60276
59894
|
avgInferenceTimeMs: 0,
|
|
60277
|
-
queueDepthTotal:
|
|
59895
|
+
queueDepthTotal: 0,
|
|
60278
59896
|
devices: [],
|
|
60279
59897
|
hardware: { hasGpu: false }
|
|
60280
59898
|
};
|
|
@@ -61254,8 +60872,7 @@ function tallyLoad(load, nodeDelta, perDevice) {
|
|
|
61254
60872
|
}), ...[...perDevice ?? /* @__PURE__ */ new Map()].filter(([deviceKey, delta]) => !known.has(deviceKey) && delta > 0).map(([deviceKey, delta]) => ({
|
|
61255
60873
|
deviceKey,
|
|
61256
60874
|
backend: deviceKey.split(":")[0] ?? deviceKey,
|
|
61257
|
-
attachedCameras: delta
|
|
61258
|
-
queueDepthTotal: 0
|
|
60875
|
+
attachedCameras: delta
|
|
61259
60876
|
}))];
|
|
61260
60877
|
return {
|
|
61261
60878
|
...load,
|
|
@@ -64376,8 +63993,8 @@ function migrateCameraSettings(cameraMap) {
|
|
|
64376
63993
|
* refused rather than substituted (D54). Reset happens to the STORE, before
|
|
64377
63994
|
* anything is resolved.
|
|
64378
63995
|
*
|
|
64379
|
-
*
|
|
64380
|
-
*
|
|
63996
|
+
* The wholesale `pipelineByAgent` override is not swept: it carries step
|
|
63997
|
+
* STRUCTURE only, and provisioning never reads a `modelId` from it.
|
|
64381
63998
|
*/
|
|
64382
63999
|
/** The one predicate: a pin to a deleted catalog id that no custom model owns. */
|
|
64383
64000
|
function pinNamesRemovedModel(stepId, modelId, isCustom) {
|
|
@@ -64626,8 +64243,7 @@ async function redispatchAffected(deps, cleared) {
|
|
|
64626
64243
|
/**
|
|
64627
64244
|
* `orchestrator-store-schemas.ts` — whole-blob Zod schemas for the
|
|
64628
64245
|
* orchestrator's addon-store keys that persist an ENTIRE collection
|
|
64629
|
-
* under a single key (`nodeBindings`, `
|
|
64630
|
-
* `cameraSettings`).
|
|
64246
|
+
* under a single key (`nodeBindings`, `agentSettings`, `cameraSettings`).
|
|
64631
64247
|
*
|
|
64632
64248
|
* These back the durable-state primitive (`this.state(KEY, Schema, {})`)
|
|
64633
64249
|
* so a hand-written serializer can never silently drop a field on save:
|
|
@@ -64640,32 +64256,7 @@ async function redispatchAffected(deps, cleared) {
|
|
|
64640
64256
|
* falls back to the empty map on a whole-blob parse failure, so the
|
|
64641
64257
|
* schema is kept faithful to the on-disk shape rather than overly strict.
|
|
64642
64258
|
*/
|
|
64643
|
-
var EngineChoiceSchema = object({
|
|
64644
|
-
runtime: _enum(["python", "node"]).transform(() => "python"),
|
|
64645
|
-
backend: string(),
|
|
64646
|
-
format: string(),
|
|
64647
|
-
device: string().optional()
|
|
64648
|
-
});
|
|
64649
64259
|
var NodeBindingsSchema = record(string(), record(string(), string()));
|
|
64650
|
-
var StoredPipelineConfigSchema = object({
|
|
64651
|
-
engine: EngineChoiceSchema.optional(),
|
|
64652
|
-
steps: array(PipelineStepInputSchema).readonly(),
|
|
64653
|
-
audio: object({
|
|
64654
|
-
engine: EngineChoiceSchema.optional(),
|
|
64655
|
-
modelId: string().optional(),
|
|
64656
|
-
enabled: boolean(),
|
|
64657
|
-
settings: record(string(), unknown()).readonly().optional()
|
|
64658
|
-
}).nullable().optional()
|
|
64659
|
-
});
|
|
64660
|
-
var StoredPipelineTemplateSchema = object({
|
|
64661
|
-
id: string(),
|
|
64662
|
-
name: string(),
|
|
64663
|
-
description: string().optional(),
|
|
64664
|
-
config: StoredPipelineConfigSchema,
|
|
64665
|
-
createdAt: string(),
|
|
64666
|
-
updatedAt: string()
|
|
64667
|
-
});
|
|
64668
|
-
var TemplatesSchema = record(string(), StoredPipelineTemplateSchema);
|
|
64669
64260
|
var StoredAgentAddonConfigSchema = object({
|
|
64670
64261
|
enabled: boolean(),
|
|
64671
64262
|
modelId: string().optional(),
|
|
@@ -64770,7 +64361,6 @@ var PipelineSettingsStore = class PipelineSettingsStore {
|
|
|
64770
64361
|
blobWriteLock = new KeyedAsyncLock({ isShuttingDown: () => this.disposed });
|
|
64771
64362
|
static AGENT_SETTINGS_LOCK_KEY = "agentSettings";
|
|
64772
64363
|
_nodeBindingsState = null;
|
|
64773
|
-
_templatesState = null;
|
|
64774
64364
|
_agentSettingsState = null;
|
|
64775
64365
|
_cameraSettingsState = null;
|
|
64776
64366
|
_bindingsMigrationDoneState = null;
|
|
@@ -64779,10 +64369,6 @@ var PipelineSettingsStore = class PipelineSettingsStore {
|
|
|
64779
64369
|
if (!this._nodeBindingsState) this._nodeBindingsState = this.deps.state("nodeBindings", NodeBindingsSchema, {});
|
|
64780
64370
|
return this._nodeBindingsState;
|
|
64781
64371
|
}
|
|
64782
|
-
get templatesState() {
|
|
64783
|
-
if (!this._templatesState) this._templatesState = this.deps.state("templates", TemplatesSchema, {});
|
|
64784
|
-
return this._templatesState;
|
|
64785
|
-
}
|
|
64786
64372
|
get agentSettingsState() {
|
|
64787
64373
|
if (!this._agentSettingsState) this._agentSettingsState = this.deps.state("agentSettings", AgentSettingsMapSchema, {});
|
|
64788
64374
|
return this._agentSettingsState;
|
|
@@ -65065,59 +64651,6 @@ var PipelineSettingsStore = class PipelineSettingsStore {
|
|
|
65065
64651
|
return rest;
|
|
65066
64652
|
});
|
|
65067
64653
|
}
|
|
65068
|
-
/** Read the templates map from the addon store via the durable handle. */
|
|
65069
|
-
async readTemplatesMap() {
|
|
65070
|
-
const raw = await this.templatesState.get();
|
|
65071
|
-
const out = {};
|
|
65072
|
-
for (const [key, value] of Object.entries(raw)) if (this.isPipelineTemplate(value)) out[key] = value;
|
|
65073
|
-
return out;
|
|
65074
|
-
}
|
|
65075
|
-
async listTemplates() {
|
|
65076
|
-
const templates = await this.readTemplatesMap();
|
|
65077
|
-
return Object.values(templates).slice().toSorted((a, b) => a.name.localeCompare(b.name));
|
|
65078
|
-
}
|
|
65079
|
-
async saveTemplate(input) {
|
|
65080
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
65081
|
-
const template = {
|
|
65082
|
-
id: this.generateTemplateId(),
|
|
65083
|
-
name: input.name,
|
|
65084
|
-
description: input.description,
|
|
65085
|
-
config: input.config,
|
|
65086
|
-
createdAt: now,
|
|
65087
|
-
updatedAt: now
|
|
65088
|
-
};
|
|
65089
|
-
const templates = await this.readTemplatesMap();
|
|
65090
|
-
templates[template.id] = template;
|
|
65091
|
-
await this.templatesState.set(templates);
|
|
65092
|
-
this.deps.logger.info("template saved", { meta: {
|
|
65093
|
-
templateId: template.id,
|
|
65094
|
-
name: template.name
|
|
65095
|
-
} });
|
|
65096
|
-
return template;
|
|
65097
|
-
}
|
|
65098
|
-
async updateTemplate(input) {
|
|
65099
|
-
const templates = await this.readTemplatesMap();
|
|
65100
|
-
const existing = templates[input.id];
|
|
65101
|
-
if (!existing) throw new Error(`updateTemplate: template '${input.id}' not found`);
|
|
65102
|
-
const next = {
|
|
65103
|
-
...existing,
|
|
65104
|
-
...input.name !== void 0 ? { name: input.name } : {},
|
|
65105
|
-
...input.description !== void 0 ? { description: input.description } : {},
|
|
65106
|
-
...input.config !== void 0 ? { config: input.config } : {},
|
|
65107
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
65108
|
-
};
|
|
65109
|
-
templates[input.id] = next;
|
|
65110
|
-
await this.templatesState.set(templates);
|
|
65111
|
-
return next;
|
|
65112
|
-
}
|
|
65113
|
-
async deleteTemplate(input) {
|
|
65114
|
-
const templates = await this.readTemplatesMap();
|
|
65115
|
-
if (!templates[input.id]) return { success: true };
|
|
65116
|
-
delete templates[input.id];
|
|
65117
|
-
await this.templatesState.set(templates);
|
|
65118
|
-
this.deps.logger.info("template deleted", { meta: { templateId: input.id } });
|
|
65119
|
-
return { success: true };
|
|
65120
|
-
}
|
|
65121
64654
|
catalogCache = /* @__PURE__ */ new Map();
|
|
65122
64655
|
/**
|
|
65123
64656
|
* A node's `PipelineSchema`: the cached answer when fresh, else ONE live
|
|
@@ -65679,21 +65212,6 @@ var PipelineSettingsStore = class PipelineSettingsStore {
|
|
|
65679
65212
|
const v = value;
|
|
65680
65213
|
return Array.isArray(v["steps"]);
|
|
65681
65214
|
}
|
|
65682
|
-
isPipelineTemplate(value) {
|
|
65683
|
-
if (!value || typeof value !== "object") return false;
|
|
65684
|
-
const v = value;
|
|
65685
|
-
return typeof v["id"] === "string" && typeof v["name"] === "string" && typeof v["createdAt"] === "string" && typeof v["updatedAt"] === "string" && this.isCameraPipelineConfig(v["config"]);
|
|
65686
|
-
}
|
|
65687
|
-
/**
|
|
65688
|
-
* Generate a short template id. Collision risk at N≤1000 templates is
|
|
65689
|
-
* effectively zero (12 hex chars = 48 bits of entropy). Not a UUID
|
|
65690
|
-
* because the persisted shape is a plain map keyed by id and shorter
|
|
65691
|
-
* keys keep the JSON compact.
|
|
65692
|
-
*/
|
|
65693
|
-
generateTemplateId() {
|
|
65694
|
-
const rand = Math.random().toString(36).slice(2, 8);
|
|
65695
|
-
return `tpl_${Date.now().toString(36).slice(-6)}${rand}`;
|
|
65696
|
-
}
|
|
65697
65215
|
};
|
|
65698
65216
|
/**
|
|
65699
65217
|
* The camera's override for one accelerator, with its CAMERA-WIDE settings
|
|
@@ -69342,6 +68860,10 @@ async function buildOrchestratorControllers(deps) {
|
|
|
69342
68860
|
onCensus: (entries) => {
|
|
69343
68861
|
motionSliceGate?.noteCensus(entries);
|
|
69344
68862
|
providerSliceGate?.refreshIfStale("runner-census");
|
|
68863
|
+
},
|
|
68864
|
+
eligibleDeviceKeys: async (nodeId) => {
|
|
68865
|
+
const read = await deps.getEligibleInferenceDevicesIfCached(nodeId);
|
|
68866
|
+
return read.kind === "eligible" ? Object.keys(read.eligible) : null;
|
|
69345
68867
|
}
|
|
69346
68868
|
});
|
|
69347
68869
|
/**
|
|
@@ -70200,12 +69722,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
70200
69722
|
id: CLUSTER_MODEL_SECTION_ID,
|
|
70201
69723
|
title: "Enrichment models",
|
|
70202
69724
|
tab: "pipeline",
|
|
70203
|
-
description: "The
|
|
69725
|
+
description: "The face and search encoders, one each for the whole cluster: each fills a single shared index, and vectors from two models cannot be compared. Changing one keeps what is stored but hides it from matching and search until it is re-embedded.",
|
|
70204
69726
|
fields: [...CLUSTER_MODEL_SCOPED_STEPS.map((step) => ({
|
|
70205
69727
|
key: clusterModelSettingKey(step.stepId),
|
|
70206
69728
|
type: "select",
|
|
70207
69729
|
label: step.label,
|
|
70208
|
-
description: `
|
|
69730
|
+
description: `Used on every node. A node that has no build of this model skips the step (and logs it) rather than use another model. Changing it hides what is already in ${step.indexName} until it is re-embedded.`,
|
|
70209
69731
|
options: step.options.map((o) => ({
|
|
70210
69732
|
value: o.id,
|
|
70211
69733
|
label: o.label
|
|
@@ -70227,12 +69749,12 @@ function buildGlobalSettingsSections(options) {
|
|
|
70227
69749
|
id: DETAIL_CROP_SECTION_ID,
|
|
70228
69750
|
title: "Enrichment crop",
|
|
70229
69751
|
tab: "pipeline",
|
|
70230
|
-
description: "How the crop
|
|
69752
|
+
description: "How the crop handed to the search, face and plate models is cut from the frame. One value for the whole cluster, because search results are only comparable when every crop is cut the same way. After changing it, rebuild the search index (Camera → Semantic search index → Rebuild).",
|
|
70231
69753
|
fields: [{
|
|
70232
69754
|
key: DETAIL_CROP_PADDING_KEY,
|
|
70233
69755
|
type: "slider",
|
|
70234
69756
|
label: "Crop margin",
|
|
70235
|
-
description: "
|
|
69757
|
+
description: "Extra margin added on each side of the detection box, as a fraction of its size. 0 = tight box, 0.15 = default. Search works better with some surroundings in the crop.",
|
|
70236
69758
|
min: DETAIL_CROP_PADDING_FIELD.min,
|
|
70237
69759
|
max: DETAIL_CROP_PADDING_FIELD.max,
|
|
70238
69760
|
step: DETAIL_CROP_PADDING_FIELD.step,
|
|
@@ -70242,7 +69764,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70242
69764
|
key: DETAIL_CROP_SQUARE_KEY,
|
|
70243
69765
|
type: "boolean",
|
|
70244
69766
|
label: "Square the crop",
|
|
70245
|
-
description: "
|
|
69767
|
+
description: "Widen the crop to a square so a tall subject is not squashed when the model resizes it. Off by default because the existing index was built without it.",
|
|
70246
69768
|
default: DEFAULT_DETAIL_CROP_CONVENTION.square
|
|
70247
69769
|
}]
|
|
70248
69770
|
},
|
|
@@ -70250,13 +69772,13 @@ function buildGlobalSettingsSections(options) {
|
|
|
70250
69772
|
id: NATIVE_LEASE_SECTION_ID,
|
|
70251
69773
|
title: "Native frame lease",
|
|
70252
69774
|
tab: "pipeline",
|
|
70253
|
-
description: "How
|
|
69775
|
+
description: "How each camera keeps full-resolution pixels so a crop taken seconds later (snapshot, face, plate) is sharp instead of cut from the small detection frame. A held frame is a whole picture (~25 MB at 4K) kept until its detections arrive; a tile is one subject, or one whole-scene copy, saved as JPEG for tens of seconds. Applies from the next session of each camera.",
|
|
70254
69776
|
fields: [
|
|
70255
69777
|
{
|
|
70256
69778
|
key: NATIVE_LEASE_HOLD_KEY,
|
|
70257
69779
|
type: "slider",
|
|
70258
69780
|
label: "Frames held at once",
|
|
70259
|
-
description: "
|
|
69781
|
+
description: "Most frames kept per camera while their detections are pending; past it the oldest is dropped. 1 to 4 are in use normally. Raise it only if a slow node drops frames (holdOverflow in the logs) — it does not make crops sharper.",
|
|
70260
69782
|
min: NATIVE_LEASE_HOLD_FIELD.min,
|
|
70261
69783
|
max: NATIVE_LEASE_HOLD_FIELD.max,
|
|
70262
69784
|
step: NATIVE_LEASE_HOLD_FIELD.step,
|
|
@@ -70268,7 +69790,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70268
69790
|
key: NATIVE_LEASE_TILE_BUDGET_KEY,
|
|
70269
69791
|
type: "slider",
|
|
70270
69792
|
label: "Subject tile RAM",
|
|
70271
|
-
description: "RAM per
|
|
69793
|
+
description: "RAM per camera for subject tiles: full-resolution crops of each detected subject, kept so a crop asked for seconds later is still sharp. A tile is ~60-120 KB. 0 = off (late crops come from the small detection frame).",
|
|
70272
69794
|
min: NATIVE_LEASE_TILE_BUDGET_FIELD.min,
|
|
70273
69795
|
max: NATIVE_LEASE_TILE_BUDGET_FIELD.max,
|
|
70274
69796
|
step: NATIVE_LEASE_TILE_BUDGET_FIELD.step,
|
|
@@ -70280,7 +69802,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70280
69802
|
key: NATIVE_LEASE_SCENE_BUDGET_KEY,
|
|
70281
69803
|
type: "slider",
|
|
70282
69804
|
label: "Scene tile RAM",
|
|
70283
|
-
description: "RAM per
|
|
69805
|
+
description: "RAM per camera for scene tiles: a full-resolution JPEG of the whole picture (~2 MB at 4K) on frames where something was detected, for key frames and whole-frame crops. 0 = off (those then fall back to the small detection frame).",
|
|
70284
69806
|
min: NATIVE_LEASE_SCENE_BUDGET_FIELD.min,
|
|
70285
69807
|
max: NATIVE_LEASE_SCENE_BUDGET_FIELD.max,
|
|
70286
69808
|
step: NATIVE_LEASE_SCENE_BUDGET_FIELD.step,
|
|
@@ -70292,7 +69814,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70292
69814
|
key: NATIVE_LEASE_BUDGET_KEY,
|
|
70293
69815
|
type: "slider",
|
|
70294
69816
|
label: "Lease RAM ceiling",
|
|
70295
|
-
description: "
|
|
69817
|
+
description: "Safety ceiling on the RAM held frames may use per camera; the frame count above is what normally limits it. Lower it on a small host. 0 turns full-resolution crops off almost entirely — for diagnosis only.",
|
|
70296
69818
|
min: NATIVE_LEASE_BUDGET_FIELD.min,
|
|
70297
69819
|
max: NATIVE_LEASE_BUDGET_FIELD.max,
|
|
70298
69820
|
step: NATIVE_LEASE_BUDGET_FIELD.step,
|
|
@@ -70304,7 +69826,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70304
69826
|
key: NATIVE_LEASE_ACTIVITY_KEY,
|
|
70305
69827
|
type: "slider",
|
|
70306
69828
|
label: "Demand window",
|
|
70307
|
-
description: "
|
|
69829
|
+
description: "Keep full-resolution pixels only within this long of the last crop request, so a camera nobody crops costs nothing; the first crop after a quiet spell falls back once. 0 = always keep (heavy on small hosts).",
|
|
70308
69830
|
min: NATIVE_LEASE_ACTIVITY_FIELD.min,
|
|
70309
69831
|
max: NATIVE_LEASE_ACTIVITY_FIELD.max,
|
|
70310
69832
|
step: NATIVE_LEASE_ACTIVITY_FIELD.step,
|
|
@@ -70317,7 +69839,7 @@ function buildGlobalSettingsSections(options) {
|
|
|
70317
69839
|
key: NATIVE_LEASE_ADMISSION_KEY,
|
|
70318
69840
|
type: "select",
|
|
70319
69841
|
label: "What to retain",
|
|
70320
|
-
description: "
|
|
69842
|
+
description: "Which frames get a full-resolution copy. 'Only frames sent to inference' keeps the frames a crop can actually ask for (about 80% less RAM); 'Every delivered frame' keeps all of them.",
|
|
70321
69843
|
options: NATIVE_LEASE_ADMISSION_FIELD.options,
|
|
70322
69844
|
default: NATIVE_LEASE_ADMISSION_FIELD.default
|
|
70323
69845
|
}
|
|
@@ -70330,7 +69852,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70330
69852
|
{
|
|
70331
69853
|
key: "onDisconnect",
|
|
70332
69854
|
type: "select",
|
|
70333
|
-
label: "
|
|
69855
|
+
label: "When a node disconnects",
|
|
69856
|
+
description: "Move its unpinned cameras to other nodes, or leave them stopped.",
|
|
70334
69857
|
default: DEFAULT_FAILOVER_POLICY.onDisconnect,
|
|
70335
69858
|
options: [{
|
|
70336
69859
|
value: "migrate",
|
|
@@ -70343,7 +69866,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70343
69866
|
{
|
|
70344
69867
|
key: "pinnedOnDisconnect",
|
|
70345
69868
|
type: "select",
|
|
70346
|
-
label: "
|
|
69869
|
+
label: "Its pinned cameras",
|
|
69870
|
+
description: "Keep the pin and wait for the node, or drop the pin and move them.",
|
|
70347
69871
|
default: DEFAULT_FAILOVER_POLICY.pinnedOnDisconnect,
|
|
70348
69872
|
options: [{
|
|
70349
69873
|
value: "leave-pinned",
|
|
@@ -70356,7 +69880,8 @@ function buildGlobalSettingsSections(options) {
|
|
|
70356
69880
|
{
|
|
70357
69881
|
key: "onReconnect",
|
|
70358
69882
|
type: "select",
|
|
70359
|
-
label: "
|
|
69883
|
+
label: "When it comes back",
|
|
69884
|
+
description: "Put its cameras back where they were, or rebalance the whole cluster.",
|
|
70360
69885
|
default: DEFAULT_FAILOVER_POLICY.onReconnect,
|
|
70361
69886
|
options: [{
|
|
70362
69887
|
value: "restore",
|
|
@@ -71853,7 +71378,7 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
71853
71378
|
nodeLifecycle = null;
|
|
71854
71379
|
/**
|
|
71855
71380
|
* The 3-level pipeline settings store (agent + camera settings maps,
|
|
71856
|
-
*
|
|
71381
|
+
* pipeline-executor catalog cache) plus the co-declared
|
|
71857
71382
|
* `nodeBindings` capability-binding map and the one-shot bindings-
|
|
71858
71383
|
* migration guard flag — see `pipeline-settings-store.ts` (S4
|
|
71859
71384
|
* extraction, cluster C11). Constructed early in `onInitialize` (before
|
|
@@ -72357,7 +71882,7 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
72357
71882
|
async getAgentLoad() {
|
|
72358
71883
|
await this.loadService.refreshDecodeHwaccels();
|
|
72359
71884
|
await this.loadService.collectAgentLoad();
|
|
72360
|
-
return this.loadService.
|
|
71885
|
+
return this.loadService.reportedAgentLoad();
|
|
72361
71886
|
}
|
|
72362
71887
|
async getGlobalMetrics() {
|
|
72363
71888
|
const summaries = await this.getAgentLoad();
|
|
@@ -73415,18 +72940,6 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
|
|
|
73415
72940
|
const resolved = await this.settingsStore.resolvePipelineForDevice(deviceId);
|
|
73416
72941
|
this.emitCameraUpdated(deviceId, resolved);
|
|
73417
72942
|
}
|
|
73418
|
-
async listTemplates() {
|
|
73419
|
-
return this.settingsStore.listTemplates();
|
|
73420
|
-
}
|
|
73421
|
-
async saveTemplate(input) {
|
|
73422
|
-
return this.settingsStore.saveTemplate(input);
|
|
73423
|
-
}
|
|
73424
|
-
async updateTemplate(input) {
|
|
73425
|
-
return this.settingsStore.updateTemplate(input);
|
|
73426
|
-
}
|
|
73427
|
-
async deleteTemplate(input) {
|
|
73428
|
-
return this.settingsStore.deleteTemplate(input);
|
|
73429
|
-
}
|
|
73430
72943
|
/**
|
|
73431
72944
|
* The per-camera FUNCTION SWITCH group (D61) — derived, never stored.
|
|
73432
72945
|
*
|