@camstack/addon-export-alexa 1.2.134 → 1.2.136
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/export-alexa.addon.js +146 -482
- package/dist/export-alexa.addon.mjs +146 -482
- package/lambda-template/README.md +49 -21
- package/lambda-template/aws.js +32 -16
- package/lambda-template/broker.js +3 -3
- package/lambda-template/debug-trace.js +100 -0
- package/lambda-template/index.js +19 -8
- package/lambda-template/secrets.js +24 -21
- package/package.json +1 -1
|
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
//#endregion
|
|
27
27
|
let node_crypto = require("node:crypto");
|
|
28
28
|
node_crypto = __toESM(node_crypto, 1);
|
|
29
|
-
//#region ../types/dist/event-category-
|
|
29
|
+
//#region ../types/dist/event-category-B_0XEcLF.mjs
|
|
30
30
|
var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
31
31
|
EventCategory["SystemBoot"] = "system.boot";
|
|
32
32
|
EventCategory["SystemAddonsReady"] = "system.addons-ready";
|
|
@@ -527,15 +527,6 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
527
527
|
EventCategory["AgentWsDisconnected"] = "agent.ws.disconnected";
|
|
528
528
|
EventCategory["AgentBackupActivated"] = "agent.backup.activated";
|
|
529
529
|
EventCategory["OrchestrationSettingsUpdated"] = "orchestration.settings-updated";
|
|
530
|
-
/**
|
|
531
|
-
* Per-agent hwaccel preference changed (user override set, cleared, or
|
|
532
|
-
* re-probed). Observability event — decoders pull the current pref at
|
|
533
|
-
* `createSession`, so running sessions keep their current backend until
|
|
534
|
-
* they rotate naturally (camera add/remove, stream restart). Future
|
|
535
|
-
* work can wire a listener in stream-broker that force-rotates live
|
|
536
|
-
* sessions; for now this event powers logs + admin-UI toast feedback.
|
|
537
|
-
*/
|
|
538
|
-
EventCategory["PipelineAgentHwaccelChanged"] = "pipeline.agent-hwaccel-changed";
|
|
539
530
|
EventCategory["MotionAnalysis"] = "detection.motion-analysis";
|
|
540
531
|
/** All raw motion zones from CCL before minArea filter — for UI debug overlay. */
|
|
541
532
|
EventCategory["MotionZonesRaw"] = "detection.motion-zones-raw";
|
|
@@ -5406,7 +5397,7 @@ var ZodIssueCode = {
|
|
|
5406
5397
|
var ZodFirstPartyTypeKind;
|
|
5407
5398
|
ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {});
|
|
5408
5399
|
//#endregion
|
|
5409
|
-
//#region ../types/dist/sleep-
|
|
5400
|
+
//#region ../types/dist/sleep-BNeXenvr.mjs
|
|
5410
5401
|
/**
|
|
5411
5402
|
* The audio chunk plane's byte format, and the ONE expansion from a coded
|
|
5412
5403
|
* window to float samples (D455).
|
|
@@ -6772,32 +6763,12 @@ object({
|
|
|
6772
6763
|
audioCodec: string().optional(),
|
|
6773
6764
|
metadata: record(string(), unknown()).readonly().optional()
|
|
6774
6765
|
});
|
|
6775
|
-
var EncodedPacketSchema = object({
|
|
6776
|
-
type: _enum(["video", "audio"]),
|
|
6777
|
-
data: _instanceof(Uint8Array),
|
|
6778
|
-
pts: number(),
|
|
6779
|
-
dts: number(),
|
|
6780
|
-
keyframe: boolean(),
|
|
6781
|
-
codec: string()
|
|
6782
|
-
});
|
|
6783
|
-
var DecodedFrameSchema = object({
|
|
6784
|
-
data: _instanceof(Uint8Array),
|
|
6785
|
-
width: number(),
|
|
6786
|
-
height: number(),
|
|
6787
|
-
format: _enum([
|
|
6788
|
-
"jpeg",
|
|
6789
|
-
"rgb",
|
|
6790
|
-
"bgr",
|
|
6791
|
-
"yuv420",
|
|
6792
|
-
"gray"
|
|
6793
|
-
]),
|
|
6794
|
-
timestamp: number()
|
|
6795
|
-
});
|
|
6796
6766
|
/**
|
|
6797
6767
|
* Wire schema for `FrameHandle` — a zero-pixel, serialisable reference to a
|
|
6798
6768
|
* frame in a shared-memory ring (Phase 5 / D9). Mirrors the `FrameHandle` TS
|
|
6799
|
-
* interface in `interfaces/frame-handle.ts` field-for-field so a
|
|
6800
|
-
*
|
|
6769
|
+
* interface in `interfaces/frame-handle.ts` field-for-field so a cap method
|
|
6770
|
+
* (the runner's native-crop and pipeline-executor inputs) can carry handles
|
|
6771
|
+
* over tRPC / Moleculer.
|
|
6801
6772
|
*
|
|
6802
6773
|
* The `satisfies` assertion below pins this schema to the interface: if a
|
|
6803
6774
|
* field is added to / removed from `FrameHandle` without a matching schema
|
|
@@ -6823,50 +6794,6 @@ var FrameHandleSchema = object({
|
|
|
6823
6794
|
slotCount: number().int().positive()
|
|
6824
6795
|
});
|
|
6825
6796
|
/**
|
|
6826
|
-
* Pixel format a frame-handle subscriber can request from the broker
|
|
6827
|
-
* (Phase 5 / D9). The packed, raster subset of `FrameFormat` — the formats a
|
|
6828
|
-
* `frameSink: 'shm'` decoder session can write into a `FrameRing` slot.
|
|
6829
|
-
* `jpeg` is excluded: a variable-length stream is not a fixed-stride ring
|
|
6830
|
-
* payload, and no decoded-frame consumer requests it over the shm plane.
|
|
6831
|
-
*/
|
|
6832
|
-
var FrameHandleFormatSchema = _enum([
|
|
6833
|
-
"rgb",
|
|
6834
|
-
"bgr",
|
|
6835
|
-
"yuv420",
|
|
6836
|
-
"gray"
|
|
6837
|
-
]);
|
|
6838
|
-
/**
|
|
6839
|
-
* Input for `stream-broker.subscribeFrames` (Phase 5 / D9). A consumer asks the
|
|
6840
|
-
* broker for a `FrameHandle` stream of one `format`; the broker maintains one
|
|
6841
|
-
* shared-memory ring per `(brokerId, format)` actually requested, so a `gray`
|
|
6842
|
-
* subscriber (motion) and an `rgb` subscriber (detection) each read the format
|
|
6843
|
-
* they asked for with no broker-side conversion.
|
|
6844
|
-
*/
|
|
6845
|
-
var SubscribeFramesInputSchema = object({
|
|
6846
|
-
brokerId: string(),
|
|
6847
|
-
format: FrameHandleFormatSchema,
|
|
6848
|
-
/**
|
|
6849
|
-
* Optional reader-side cadence hint in frames per second. The broker does
|
|
6850
|
-
* NOT throttle — latest-wins ring reads drop frames implicitly for a slow
|
|
6851
|
-
* consumer. The value is echoed back in `SubscribeFramesResult.maxFps` so
|
|
6852
|
-
* the consumer can pace its own `pullFrameHandles` polling.
|
|
6853
|
-
*/
|
|
6854
|
-
maxFps: number().positive().optional(),
|
|
6855
|
-
/** Short caller-identity tag (`motion`, `detection`, …) for diagnostics. */
|
|
6856
|
-
tag: string().optional()
|
|
6857
|
-
});
|
|
6858
|
-
/**
|
|
6859
|
-
* Result of `stream-broker.subscribeFrames`. The consumer then polls
|
|
6860
|
-
* `pullFrameHandles({ subscriptionId, maxCount })` and feeds each returned
|
|
6861
|
-
* `FrameHandle` to a `FrameRingReader`.
|
|
6862
|
-
*/
|
|
6863
|
-
var SubscribeFramesResultSchema = object({
|
|
6864
|
-
/** Opaque id the consumer passes to `pullFrameHandles` / `unsubscribeFrames`. */
|
|
6865
|
-
subscriptionId: string(),
|
|
6866
|
-
/** Reader-side cadence hint (frames/s) — echoes `SubscribeFramesInput.maxFps`. */
|
|
6867
|
-
maxFps: number().nonnegative()
|
|
6868
|
-
});
|
|
6869
|
-
/**
|
|
6870
6797
|
* Wire schema for a decoded audio chunk (Phase 5 / D9). Mirrors the
|
|
6871
6798
|
* `DecodedAudioChunk` TS interface in `interfaces/stream-broker.ts`: PCM
|
|
6872
6799
|
* sample bytes plus the track parameters a consumer needs to interpret them.
|
|
@@ -6874,8 +6801,8 @@ var SubscribeFramesResultSchema = object({
|
|
|
6874
6801
|
* Audio chunks are tiny (a ~500ms AudioCodecSession window is a few KB of
|
|
6875
6802
|
* Float32 PCM), so unlike video frames they ship their bytes INLINE over
|
|
6876
6803
|
* tRPC / Moleculer — no shared-memory plane. `data` is typed `Uint8Array`
|
|
6877
|
-
* (the wire-serialisable supertype of `Buffer`)
|
|
6878
|
-
*
|
|
6804
|
+
* (the wire-serialisable supertype of `Buffer`); a `Buffer` is assignable to
|
|
6805
|
+
* it.
|
|
6879
6806
|
*/
|
|
6880
6807
|
var AudioChunkFormatSchema = _enum(AUDIO_CHUNK_FORMATS);
|
|
6881
6808
|
var DecodedAudioChunkSchema = object({
|
|
@@ -6893,11 +6820,10 @@ var DecodedAudioChunkSchema = object({
|
|
|
6893
6820
|
format: AudioChunkFormatSchema.optional()
|
|
6894
6821
|
});
|
|
6895
6822
|
/**
|
|
6896
|
-
* Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9).
|
|
6897
|
-
*
|
|
6898
|
-
*
|
|
6899
|
-
*
|
|
6900
|
-
* `pullAudioChunks`.
|
|
6823
|
+
* Input for `stream-broker.subscribeAudioChunks` (Phase 5 / D9). Audio ships
|
|
6824
|
+
* its bytes inline: a consumer asks the broker for the decoded audio-chunk
|
|
6825
|
+
* stream of one broker; the broker keeps a per-subscription bounded FIFO queue
|
|
6826
|
+
* the consumer drains via `pullAudioChunks`.
|
|
6901
6827
|
*/
|
|
6902
6828
|
var SubscribeAudioChunksInputSchema = object({
|
|
6903
6829
|
brokerId: string(),
|
|
@@ -6928,9 +6854,7 @@ var BrokerStatsSchema = object({
|
|
|
6928
6854
|
"stopped"
|
|
6929
6855
|
]),
|
|
6930
6856
|
inputFps: number(),
|
|
6931
|
-
decodeFps: number(),
|
|
6932
6857
|
encodedSubscribers: number(),
|
|
6933
|
-
decodedSubscribers: number(),
|
|
6934
6858
|
uptimeMs: number(),
|
|
6935
6859
|
bitrateKbps: number(),
|
|
6936
6860
|
idrIntervalMs: number(),
|
|
@@ -6943,14 +6867,6 @@ var BrokerStatsSchema = object({
|
|
|
6943
6867
|
preBufferMs: number(),
|
|
6944
6868
|
preBufferPackets: number(),
|
|
6945
6869
|
/**
|
|
6946
|
-
* Moleculer node id of the decoder provider currently servicing this
|
|
6947
|
-
* stream's decoded subscribers. `null` until the deferred decoder is
|
|
6948
|
-
* created (no decoded clients yet, or codec not detected). Surfaces the
|
|
6949
|
-
* runtime decoder placement so the UI can show "Decoder: <agent>" without
|
|
6950
|
-
* a separate cap call per broker.
|
|
6951
|
-
*/
|
|
6952
|
-
decoderNodeId: string().nullable(),
|
|
6953
|
-
/**
|
|
6954
6870
|
* Detected audio track parameters from the RTSP DESCRIBE / SDP. `null`
|
|
6955
6871
|
* when the stream has no audio track or the broker is in cold start.
|
|
6956
6872
|
* `supported = false` means the codec was detected but the local
|
|
@@ -10473,70 +10389,6 @@ var StorageLocationDeclarationSchema = object({
|
|
|
10473
10389
|
"backup"
|
|
10474
10390
|
]).optional()
|
|
10475
10391
|
});
|
|
10476
|
-
var DecoderStatsSchema = object({
|
|
10477
|
-
inputFps: number(),
|
|
10478
|
-
outputFps: number(),
|
|
10479
|
-
avgDecodeTimeMs: number(),
|
|
10480
|
-
droppedFrames: number(),
|
|
10481
|
-
/**
|
|
10482
|
-
* Pull-mode adaptive-fps telemetry (optional — only pull sessions run the
|
|
10483
|
-
* lag-driven controller; push sessions omit these). `lagMs` is the EWMA of
|
|
10484
|
-
* the decoder's real-time drift (rising = falling behind live); `adaptiveFps`
|
|
10485
|
-
* is the current lag-throttled emit rate (≤ `effectiveFps` ceiling).
|
|
10486
|
-
*/
|
|
10487
|
-
lagMs: number().optional(),
|
|
10488
|
-
effectiveFps: number().optional(),
|
|
10489
|
-
adaptiveFps: number().optional()
|
|
10490
|
-
});
|
|
10491
|
-
var DecoderSessionConfigSchema = object({
|
|
10492
|
-
codec: string(),
|
|
10493
|
-
maxFps: number().default(0),
|
|
10494
|
-
outputFormat: _enum([
|
|
10495
|
-
"jpeg",
|
|
10496
|
-
"rgb",
|
|
10497
|
-
"bgr",
|
|
10498
|
-
"yuv420",
|
|
10499
|
-
"gray"
|
|
10500
|
-
]).default("jpeg"),
|
|
10501
|
-
scale: number().default(1),
|
|
10502
|
-
width: number().optional(),
|
|
10503
|
-
height: number().optional(),
|
|
10504
|
-
/**
|
|
10505
|
-
* Identifier of the camera this decoder session serves. Optional
|
|
10506
|
-
* because the cap is generic (any caller could request decode), but
|
|
10507
|
-
* stream-broker passes it so decoder logs include `deviceId` for
|
|
10508
|
-
* per-camera filtering when diagnosing failures (e.g. node-av
|
|
10509
|
-
* sendPacket errors on a single hung camera).
|
|
10510
|
-
*/
|
|
10511
|
-
deviceId: number().int().nonnegative().optional(),
|
|
10512
|
-
/**
|
|
10513
|
-
* Free-form tag for log scoping. Stream-broker uses
|
|
10514
|
-
* `broker:<deviceId>/<profile>`. Decoder session logger surfaces it
|
|
10515
|
-
* on every line so `grep tag=broker:5/high` filters one camera
|
|
10516
|
-
* profile cleanly.
|
|
10517
|
-
*/
|
|
10518
|
-
tag: string().optional(),
|
|
10519
|
-
/**
|
|
10520
|
-
* Where the session delivers decoded frames (Phase 5 / D9):
|
|
10521
|
-
*
|
|
10522
|
-
* - `'callback'` (default) — the legacy pixel path: decoded frames are
|
|
10523
|
-
* buffered as `DecodedFrame`s and drained via `pullFrames`.
|
|
10524
|
-
* - `'shm'` — the shared-memory frame plane: decoded frames are written
|
|
10525
|
-
* into an OS shared-memory ring and drained as zero-pixel
|
|
10526
|
-
* `FrameHandle`s via `pullHandles`. A session is one mode or the
|
|
10527
|
-
* other — `pullFrames` returns nothing for an `'shm'` session and
|
|
10528
|
-
* `pullHandles` returns nothing for a `'callback'` session.
|
|
10529
|
-
*/
|
|
10530
|
-
frameSink: _enum(["callback", "shm"]).default("callback"),
|
|
10531
|
-
/**
|
|
10532
|
-
* Per-camera decoder DEBUG facility. When `true`, a pull-mode session emits
|
|
10533
|
-
* a throttled (~1Hz) structured `decoder debug` line (effective/adaptive fps,
|
|
10534
|
-
* real-time lag, dropped-frame delta, avg decode time, hwaccel). Mirrors the
|
|
10535
|
-
* stream-broker's `streamingDebug` gate — off by default so production logs
|
|
10536
|
-
* stay quiet and the emit path pays zero per-frame cost when disabled.
|
|
10537
|
-
*/
|
|
10538
|
-
debug: boolean().optional()
|
|
10539
|
-
});
|
|
10540
10392
|
/**
|
|
10541
10393
|
* Per-component log CHANNELS — the gate a hot path consults, and the registry
|
|
10542
10394
|
* an addon declares its channels in.
|
|
@@ -12797,13 +12649,6 @@ var BrokerRtspClientSchema = object({
|
|
|
12797
12649
|
lastRtpAt: number(),
|
|
12798
12650
|
bytesSent: number()
|
|
12799
12651
|
});
|
|
12800
|
-
var BrokerDecodedClientSchema = object({
|
|
12801
|
-
tag: string(),
|
|
12802
|
-
subscribedAt: number(),
|
|
12803
|
-
maxFps: number(),
|
|
12804
|
-
framesDelivered: number(),
|
|
12805
|
-
framesDropped: number()
|
|
12806
|
-
});
|
|
12807
12652
|
var BrokerAudioClientSchema = object({
|
|
12808
12653
|
tag: string(),
|
|
12809
12654
|
subscribedAt: number(),
|
|
@@ -12895,7 +12740,6 @@ var BrokerEncodedClientSchema = object({
|
|
|
12895
12740
|
});
|
|
12896
12741
|
var BrokerClientsSchema = object({
|
|
12897
12742
|
rtsp: array(BrokerRtspClientSchema).readonly(),
|
|
12898
|
-
decoded: array(BrokerDecodedClientSchema).readonly(),
|
|
12899
12743
|
audio: array(BrokerAudioClientSchema).readonly(),
|
|
12900
12744
|
encoded: array(BrokerEncodedClientSchema).readonly(),
|
|
12901
12745
|
pipeClients: number(),
|
|
@@ -13264,11 +13108,7 @@ method(object({
|
|
|
13264
13108
|
auth: "admin"
|
|
13265
13109
|
}), method(object({ brokerId: string() }), BrokerClientsSchema), method(object({
|
|
13266
13110
|
brokerId: string(),
|
|
13267
|
-
channel: _enum([
|
|
13268
|
-
"rtsp",
|
|
13269
|
-
"decoded",
|
|
13270
|
-
"audio"
|
|
13271
|
-
]),
|
|
13111
|
+
channel: _enum(["rtsp", "audio"]),
|
|
13272
13112
|
handle: string()
|
|
13273
13113
|
}), object({ killed: boolean() }), {
|
|
13274
13114
|
kind: "mutation",
|
|
@@ -13303,10 +13143,7 @@ method(object({
|
|
|
13303
13143
|
}), method(SubscribeAudioChunksInputSchema, SubscribeAudioChunksResultSchema, { kind: "mutation" }), method(object({
|
|
13304
13144
|
subscriptionId: string(),
|
|
13305
13145
|
maxCount: number().int().positive().default(8)
|
|
13306
|
-
}), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(
|
|
13307
|
-
subscriptionId: string(),
|
|
13308
|
-
maxCount: number().int().positive().default(4)
|
|
13309
|
-
}), array(FrameHandleSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
|
|
13146
|
+
}), array(DecodedAudioChunkSchema).readonly()), method(object({ subscriptionId: string() }), object({ released: boolean() }), { kind: "mutation" }), method(object({
|
|
13310
13147
|
brokerId: string(),
|
|
13311
13148
|
seconds: number().min(0).max(30)
|
|
13312
13149
|
}), _void(), {
|
|
@@ -14463,54 +14300,12 @@ id: union([string(), number()]) }), {
|
|
|
14463
14300
|
kind: "mutation",
|
|
14464
14301
|
auth: "admin"
|
|
14465
14302
|
});
|
|
14466
|
-
|
|
14467
|
-
* shm ring usage stats for a `frameSink: 'shm'` decoder session —
|
|
14468
|
-
* exposed via `decoder.getShmStats` so downstream consumers can
|
|
14469
|
-
* observe ring pressure (slot count, byte budget, hit/miss ratio).
|
|
14470
|
-
*/
|
|
14471
|
-
var ShmRingStatsSchema = object({
|
|
14472
|
-
sessionId: string(),
|
|
14473
|
-
slotCount: number().int(),
|
|
14474
|
-
slotByteLength: number().int(),
|
|
14475
|
-
segmentBytes: number().int(),
|
|
14476
|
-
budgetMb: number().int(),
|
|
14477
|
-
framesWritten: number().int(),
|
|
14478
|
-
getFrameHits: number().int(),
|
|
14479
|
-
getFrameMisses: number().int()
|
|
14480
|
-
});
|
|
14481
|
-
method(object({ codec: string() }), boolean()), method(_void(), object({
|
|
14303
|
+
method(_void(), object({
|
|
14482
14304
|
id: string(),
|
|
14483
14305
|
name: string(),
|
|
14484
|
-
isPullMode: boolean().optional(),
|
|
14485
|
-
priority: number().optional(),
|
|
14486
14306
|
hwaccel: string().optional(),
|
|
14487
14307
|
probedBestHwaccel: string().optional()
|
|
14488
|
-
})), method(
|
|
14489
|
-
sessionId: string(),
|
|
14490
|
-
nodeId: string()
|
|
14491
|
-
})), method(object({ sessionId: string() }), _void()), method(object({
|
|
14492
|
-
sessionId: string(),
|
|
14493
|
-
packet: EncodedPacketSchema
|
|
14494
|
-
}), _void()), method(object({
|
|
14495
|
-
sessionId: string(),
|
|
14496
|
-
url: string()
|
|
14497
|
-
}), _void()), method(object({
|
|
14498
|
-
sessionId: string(),
|
|
14499
|
-
maxCount: number().default(1),
|
|
14500
|
-
waitMs: number().optional()
|
|
14501
|
-
}), array(DecodedFrameSchema)), method(object({
|
|
14502
|
-
sessionId: string(),
|
|
14503
|
-
maxCount: number().default(1),
|
|
14504
|
-
waitMs: number().optional()
|
|
14505
|
-
}), array(FrameHandleSchema)), method(object({ handle: FrameHandleSchema }), DecodedFrameSchema.nullable()), method(object({ sessionId: string() }), ShmRingStatsSchema.nullable()), method(object({
|
|
14506
|
-
sessionId: string(),
|
|
14507
|
-
config: DecoderSessionConfigSchema.partial()
|
|
14508
|
-
}), _void()), method(object({ sessionId: string() }), DecoderStatsSchema), method(_void(), array(object({
|
|
14509
|
-
sessionId: string(),
|
|
14510
|
-
codec: string(),
|
|
14511
|
-
outputFormat: string(),
|
|
14512
|
-
createdAtMs: number()
|
|
14513
|
-
})).readonly()), method(_void(), object({ backend: string() }), {
|
|
14308
|
+
})), method(_void(), object({ backend: string() }), {
|
|
14514
14309
|
kind: "mutation",
|
|
14515
14310
|
auth: "admin"
|
|
14516
14311
|
});
|
|
@@ -21571,8 +21366,8 @@ Object.freeze(Object.fromEntries([{
|
|
|
21571
21366
|
var CLUSTER_STEP_SETTING_FIELDS = [{
|
|
21572
21367
|
stepId: "face-embedding",
|
|
21573
21368
|
key: "minLandmarkFaceSize",
|
|
21574
|
-
label: "Min face size
|
|
21575
|
-
description: "
|
|
21369
|
+
label: "Min face size to embed (detection-frame px)",
|
|
21370
|
+
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.",
|
|
21576
21371
|
type: "slider",
|
|
21577
21372
|
min: 0,
|
|
21578
21373
|
max: 64,
|
|
@@ -23624,21 +23419,6 @@ var PipelineDefaultStepSchema = lazy(() => object({
|
|
|
23624
23419
|
group: string().optional(),
|
|
23625
23420
|
settings: record(string(), unknown()).optional()
|
|
23626
23421
|
}));
|
|
23627
|
-
var PipelineTemplateStepSchema = lazy(() => object({
|
|
23628
|
-
addonId: string(),
|
|
23629
|
-
enabled: boolean(),
|
|
23630
|
-
modelId: string(),
|
|
23631
|
-
children: array(PipelineTemplateStepSchema).readonly(),
|
|
23632
|
-
settings: record(string(), unknown()).optional()
|
|
23633
|
-
}));
|
|
23634
|
-
var PipelineTemplateSchema$1 = object({
|
|
23635
|
-
id: string(),
|
|
23636
|
-
name: string(),
|
|
23637
|
-
createdAt: string(),
|
|
23638
|
-
updatedAt: string(),
|
|
23639
|
-
engine: PipelineEngineChoiceSchema,
|
|
23640
|
-
steps: array(PipelineTemplateStepSchema).readonly()
|
|
23641
|
-
});
|
|
23642
23422
|
var PipelineModelOptionSchema = object({
|
|
23643
23423
|
id: string(),
|
|
23644
23424
|
name: string(),
|
|
@@ -23850,15 +23630,7 @@ method(_void(), array(PipelineEngineChoiceSchema)), method(_void(), PipelineEngi
|
|
|
23850
23630
|
}), method(_void(), PipelineSchemaSchema), method(_void(), array(PipelineDefaultStepSchema).readonly().nullable()), method(_void(), PipelineConfigBridge), method(_void(), ConfigUISchemaBridge), method(object({
|
|
23851
23631
|
steps: array(PipelineStepInputSchema),
|
|
23852
23632
|
deviceKey: string().optional()
|
|
23853
|
-
}), PipelineValidationResultSchema), method(_void(),
|
|
23854
|
-
name: string(),
|
|
23855
|
-
steps: array(PipelineTemplateStepSchema).readonly(),
|
|
23856
|
-
engine: PipelineEngineChoiceSchema
|
|
23857
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({
|
|
23858
|
-
id: string(),
|
|
23859
|
-
name: string().optional(),
|
|
23860
|
-
steps: array(PipelineTemplateStepSchema).readonly().optional()
|
|
23861
|
-
}), PipelineTemplateSchema$1, { kind: "mutation" }), method(object({ id: string() }), _void(), { kind: "mutation" }), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
|
|
23633
|
+
}), PipelineValidationResultSchema), method(_void(), InferenceCapabilitiesBridge), method(object({ addonId: string() }), ModelAvailabilityListBridge), method(object({
|
|
23862
23634
|
addonId: string(),
|
|
23863
23635
|
modelId: string(),
|
|
23864
23636
|
format: ModelFormatSchema$2
|
|
@@ -25268,14 +25040,15 @@ var RunnerLocalLoadSchema = object({
|
|
|
25268
25040
|
* Per-inference-device live load (multi-device C4). One entry per deviceKey
|
|
25269
25041
|
* this runner currently has attached cameras on, so the orchestrator's second
|
|
25270
25042
|
* `balance()` pass (over a node's devices) weights on real per-pool session
|
|
25271
|
-
* counts. Empty on single-device / pre-multi-device runners.
|
|
25272
|
-
* per
|
|
25043
|
+
* counts. Empty on single-device / pre-multi-device runners. There is no
|
|
25044
|
+
* per-device queue depth: the inference pool's backlog has no accessor, and
|
|
25045
|
+
* a field that always read 0 was removed rather than shown as a measurement
|
|
25046
|
+
* (D762).
|
|
25273
25047
|
*/
|
|
25274
25048
|
devices: array(object({
|
|
25275
25049
|
deviceKey: string(),
|
|
25276
25050
|
backend: string(),
|
|
25277
|
-
attachedCameras: number()
|
|
25278
|
-
queueDepthTotal: number()
|
|
25051
|
+
attachedCameras: number()
|
|
25279
25052
|
})).default([]),
|
|
25280
25053
|
/** Hardware capability flags reported by this node. */
|
|
25281
25054
|
hardware: object({
|
|
@@ -25489,14 +25262,6 @@ var CameraPipelineConfigSchema = object({
|
|
|
25489
25262
|
settings: record(string(), unknown()).readonly().optional()
|
|
25490
25263
|
}).nullable().optional()
|
|
25491
25264
|
});
|
|
25492
|
-
var PipelineTemplateSchema = object({
|
|
25493
|
-
id: string(),
|
|
25494
|
-
name: string(),
|
|
25495
|
-
description: string().optional(),
|
|
25496
|
-
config: CameraPipelineConfigSchema,
|
|
25497
|
-
createdAt: string(),
|
|
25498
|
-
updatedAt: string()
|
|
25499
|
-
});
|
|
25500
25265
|
var DeviceStepConfigSchema = object({
|
|
25501
25266
|
modelId: string().optional(),
|
|
25502
25267
|
settings: record(string(), unknown()).optional(),
|
|
@@ -25606,7 +25371,10 @@ var PipelineAssignmentSchema = object({
|
|
|
25606
25371
|
});
|
|
25607
25372
|
/**
|
|
25608
25373
|
* Per-agent load summary surfaced to the load balancer + dashboards.
|
|
25609
|
-
* Aggregated from each runner's `getLocalLoad` cap call.
|
|
25374
|
+
* Aggregated from each runner's `getLocalLoad` cap call. In the
|
|
25375
|
+
* `getAgentLoad` report, a single-device node's default-pool sessions (no
|
|
25376
|
+
* `deviceKey`) are credited to its one eligible device in `load.devices` —
|
|
25377
|
+
* the default pool IS that device (D745); the balancer's census stays raw.
|
|
25610
25378
|
*/
|
|
25611
25379
|
var AgentLoadSummarySchema = object({
|
|
25612
25380
|
nodeId: string(),
|
|
@@ -25695,26 +25463,27 @@ var CameraBrokerStatusSchema = object({
|
|
|
25695
25463
|
width: number(),
|
|
25696
25464
|
height: number(),
|
|
25697
25465
|
subscribers: number(),
|
|
25698
|
-
|
|
25699
|
-
|
|
25466
|
+
/**
|
|
25467
|
+
* Encoded packets/s the broker receives from the camera. null when the
|
|
25468
|
+
* broker's stats read failed — unknown, never 0 (a 0 here reads as a stall).
|
|
25469
|
+
* There is no output rate: decoding runs in the session decode workers, not
|
|
25470
|
+
* in the broker, so the broker's own decoded-frame rate is 0 on every live
|
|
25471
|
+
* camera and is not served (D758).
|
|
25472
|
+
*/
|
|
25473
|
+
inFps: number().nullable()
|
|
25700
25474
|
})).readonly(),
|
|
25701
25475
|
webrtcSessions: number(),
|
|
25702
25476
|
rtspRestream: boolean()
|
|
25703
25477
|
});
|
|
25704
|
-
/**
|
|
25705
|
-
|
|
25706
|
-
|
|
25707
|
-
|
|
25708
|
-
|
|
25709
|
-
|
|
25710
|
-
|
|
25711
|
-
|
|
25712
|
-
var CameraDecoderStatusSchema = object({
|
|
25713
|
-
nodeId: string(),
|
|
25714
|
-
formats: array(string()).readonly(),
|
|
25715
|
-
sessionCount: number(),
|
|
25716
|
-
shm: CameraDecoderShmSchema
|
|
25717
|
-
});
|
|
25478
|
+
/**
|
|
25479
|
+
* Decoder block — WHERE decode runs (co-located with the detection node by
|
|
25480
|
+
* construction); null when the camera has no detection node. It carries no
|
|
25481
|
+
* frame counter: the shared-memory plane whose counters it used to serve is
|
|
25482
|
+
* gone, and those fields read 0 forever. Whether frames actually flow is read
|
|
25483
|
+
* from `detection.actualFps` (frames delivered to and processed by the
|
|
25484
|
+
* detector), never from a counter nothing feeds.
|
|
25485
|
+
*/
|
|
25486
|
+
var CameraDecoderStatusSchema = object({ nodeId: string() });
|
|
25718
25487
|
/** Motion block — null when motion detection is not active for this device. */
|
|
25719
25488
|
var CameraMotionStatusSchema = object({
|
|
25720
25489
|
enabled: boolean(),
|
|
@@ -26167,25 +25936,7 @@ method(object({
|
|
|
26167
25936
|
}), method(_void(), DiskReconcileJobSchema, {
|
|
26168
25937
|
kind: "mutation",
|
|
26169
25938
|
auth: "admin"
|
|
26170
|
-
}), method(_void(), DiskReconcileJobSchema, { auth: "admin" })
|
|
26171
|
-
name: string(),
|
|
26172
|
-
description: string().optional(),
|
|
26173
|
-
config: CameraPipelineConfigSchema
|
|
26174
|
-
}), PipelineTemplateSchema, {
|
|
26175
|
-
kind: "mutation",
|
|
26176
|
-
auth: "admin"
|
|
26177
|
-
}), method(object({
|
|
26178
|
-
id: string(),
|
|
26179
|
-
name: string().optional(),
|
|
26180
|
-
description: string().optional(),
|
|
26181
|
-
config: CameraPipelineConfigSchema.optional()
|
|
26182
|
-
}), PipelineTemplateSchema, {
|
|
26183
|
-
kind: "mutation",
|
|
26184
|
-
auth: "admin"
|
|
26185
|
-
}), method(object({ id: string() }), object({ success: literal(true) }), {
|
|
26186
|
-
kind: "mutation",
|
|
26187
|
-
auth: "admin"
|
|
26188
|
-
});
|
|
25939
|
+
}), method(_void(), DiskReconcileJobSchema, { auth: "admin" });
|
|
26189
25940
|
/**
|
|
26190
25941
|
* Cap → event-kind mapping for the SENSOR / CONTROL cap families — the table
|
|
26191
25942
|
* `pipeline-analytics.listEventKinds` uses to turn a linked device's bound
|
|
@@ -28405,8 +28156,6 @@ var WebrtcStreamChoiceSchema = object({
|
|
|
28405
28156
|
]).nullable(),
|
|
28406
28157
|
/** Input FPS from the camera (null for adaptive). */
|
|
28407
28158
|
inputFps: number().nullable(),
|
|
28408
|
-
/** Decoded FPS (null for adaptive). */
|
|
28409
|
-
decodeFps: number().nullable(),
|
|
28410
28159
|
/** Bitrate in kbps (null for adaptive). */
|
|
28411
28160
|
bitrateKbps: number().nullable()
|
|
28412
28161
|
});
|
|
@@ -28985,6 +28734,59 @@ var AddonAutoUpdateSchema = ChannelWithInheritSchema;
|
|
|
28985
28734
|
var RestartAddonResultSchema = unknown();
|
|
28986
28735
|
var InstallPackageResultSchema = unknown();
|
|
28987
28736
|
var ReloadPackagesResultSchema = unknown();
|
|
28737
|
+
/**
|
|
28738
|
+
* What an uninstall did on ONE node.
|
|
28739
|
+
* - `uninstalled` — removed: runner(s) stopped, caps gone, code deleted.
|
|
28740
|
+
* - `not-installed` — the node did not have it (nothing to do).
|
|
28741
|
+
* - `refused` — protected / bootstrap package; nothing touched.
|
|
28742
|
+
* - `failed` — attempted and did not complete; `error` says why.
|
|
28743
|
+
* - `pending-reconnect` — the node is OFFLINE: its record was pruned so the
|
|
28744
|
+
* back-fill never returns the package, and the stale-addon sweep removes the
|
|
28745
|
+
* copy when the node registers again (only once the hub no longer has it).
|
|
28746
|
+
*/
|
|
28747
|
+
var UninstallNodeOutcomeSchema = _enum([
|
|
28748
|
+
"uninstalled",
|
|
28749
|
+
"not-installed",
|
|
28750
|
+
"refused",
|
|
28751
|
+
"failed",
|
|
28752
|
+
"pending-reconnect"
|
|
28753
|
+
]);
|
|
28754
|
+
var UninstallNodeResultSchema = object({
|
|
28755
|
+
nodeId: string(),
|
|
28756
|
+
outcome: UninstallNodeOutcomeSchema,
|
|
28757
|
+
error: string().optional(),
|
|
28758
|
+
addonIds: array(string()).readonly(),
|
|
28759
|
+
runnersStopped: array(string()).readonly(),
|
|
28760
|
+
warnings: array(string()).readonly()
|
|
28761
|
+
});
|
|
28762
|
+
var UninstallPackageResultSchema = object({
|
|
28763
|
+
/** Every targeted node ended `uninstalled`, `not-installed` or `pending-reconnect`. */
|
|
28764
|
+
success: boolean(),
|
|
28765
|
+
packageName: string(),
|
|
28766
|
+
results: array(UninstallNodeResultSchema).readonly()
|
|
28767
|
+
});
|
|
28768
|
+
/**
|
|
28769
|
+
* `unreachable` lists online agents whose status read FAILED — absence from
|
|
28770
|
+
* `installations` is only "not installed" for a node that answered (D315).
|
|
28771
|
+
*/
|
|
28772
|
+
var PackageInstallationsSchema = object({
|
|
28773
|
+
installations: array(object({
|
|
28774
|
+
packageName: string(),
|
|
28775
|
+
nodeId: string(),
|
|
28776
|
+
nodeName: string(),
|
|
28777
|
+
isHub: boolean(),
|
|
28778
|
+
isOnline: boolean(),
|
|
28779
|
+
version: string().nullable(),
|
|
28780
|
+
addonIds: array(string()).readonly(),
|
|
28781
|
+
source: _enum(["live", "recorded"]),
|
|
28782
|
+
/** The hub installs this package too. `false` on an agent row = an orphan. */
|
|
28783
|
+
onHub: boolean()
|
|
28784
|
+
})).readonly(),
|
|
28785
|
+
unreachable: array(object({
|
|
28786
|
+
nodeId: string(),
|
|
28787
|
+
error: string()
|
|
28788
|
+
})).readonly()
|
|
28789
|
+
});
|
|
28988
28790
|
var BulkUpdateItemStatusSchema = _enum([
|
|
28989
28791
|
"queued",
|
|
28990
28792
|
"updating",
|
|
@@ -29067,10 +28869,14 @@ method(_void(), array(AddonListItemSchema).readonly()), method(object({
|
|
|
29067
28869
|
}), method(object({ packageName: string() }), InstallPackageResultSchema, {
|
|
29068
28870
|
kind: "mutation",
|
|
29069
28871
|
auth: "admin"
|
|
29070
|
-
}), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
|
|
28872
|
+
}), method(_void(), boolean()), method(_void(), array(unknown()).readonly()), method(object({
|
|
28873
|
+
packageName: string().min(1),
|
|
28874
|
+
nodeId: string().optional(),
|
|
28875
|
+
everywhere: boolean().optional()
|
|
28876
|
+
}), UninstallPackageResultSchema, {
|
|
29071
28877
|
kind: "mutation",
|
|
29072
28878
|
auth: "admin"
|
|
29073
|
-
}), method(_void(), ReloadPackagesResultSchema, {
|
|
28879
|
+
}), method(object({ packageName: string().optional() }), PackageInstallationsSchema, { auth: "admin" }), method(_void(), ReloadPackagesResultSchema, {
|
|
29074
28880
|
kind: "mutation",
|
|
29075
28881
|
auth: "admin"
|
|
29076
28882
|
}), method(object({ query: string().optional() }), array(SearchResultSchema)), method(object({ nodeId: string().optional() }), array(PackageUpdateSchema).readonly(), { auth: "admin" }), method(object({
|
|
@@ -37359,6 +37165,12 @@ Object.freeze({
|
|
|
37359
37165
|
addonId: null,
|
|
37360
37166
|
access: "view"
|
|
37361
37167
|
},
|
|
37168
|
+
"addons.listInstallations": {
|
|
37169
|
+
capName: "addons",
|
|
37170
|
+
capScope: "system",
|
|
37171
|
+
addonId: null,
|
|
37172
|
+
access: "view"
|
|
37173
|
+
},
|
|
37362
37174
|
"addons.listJobs": {
|
|
37363
37175
|
capName: "addons",
|
|
37364
37176
|
capScope: "system",
|
|
@@ -38541,90 +38353,18 @@ Object.freeze({
|
|
|
38541
38353
|
addonId: null,
|
|
38542
38354
|
access: "create"
|
|
38543
38355
|
},
|
|
38544
|
-
"decoder.createSession": {
|
|
38545
|
-
capName: "decoder",
|
|
38546
|
-
capScope: "system",
|
|
38547
|
-
addonId: null,
|
|
38548
|
-
access: "view"
|
|
38549
|
-
},
|
|
38550
|
-
"decoder.destroySession": {
|
|
38551
|
-
capName: "decoder",
|
|
38552
|
-
capScope: "system",
|
|
38553
|
-
addonId: null,
|
|
38554
|
-
access: "delete"
|
|
38555
|
-
},
|
|
38556
|
-
"decoder.getFrame": {
|
|
38557
|
-
capName: "decoder",
|
|
38558
|
-
capScope: "system",
|
|
38559
|
-
addonId: null,
|
|
38560
|
-
access: "view"
|
|
38561
|
-
},
|
|
38562
38356
|
"decoder.getInfo": {
|
|
38563
38357
|
capName: "decoder",
|
|
38564
38358
|
capScope: "system",
|
|
38565
38359
|
addonId: null,
|
|
38566
38360
|
access: "view"
|
|
38567
38361
|
},
|
|
38568
|
-
"decoder.getShmStats": {
|
|
38569
|
-
capName: "decoder",
|
|
38570
|
-
capScope: "system",
|
|
38571
|
-
addonId: null,
|
|
38572
|
-
access: "view"
|
|
38573
|
-
},
|
|
38574
|
-
"decoder.getStats": {
|
|
38575
|
-
capName: "decoder",
|
|
38576
|
-
capScope: "system",
|
|
38577
|
-
addonId: null,
|
|
38578
|
-
access: "view"
|
|
38579
|
-
},
|
|
38580
|
-
"decoder.listActiveSessions": {
|
|
38581
|
-
capName: "decoder",
|
|
38582
|
-
capScope: "system",
|
|
38583
|
-
addonId: null,
|
|
38584
|
-
access: "view"
|
|
38585
|
-
},
|
|
38586
|
-
"decoder.openStream": {
|
|
38587
|
-
capName: "decoder",
|
|
38588
|
-
capScope: "system",
|
|
38589
|
-
addonId: null,
|
|
38590
|
-
access: "view"
|
|
38591
|
-
},
|
|
38592
|
-
"decoder.pullFrames": {
|
|
38593
|
-
capName: "decoder",
|
|
38594
|
-
capScope: "system",
|
|
38595
|
-
addonId: null,
|
|
38596
|
-
access: "view"
|
|
38597
|
-
},
|
|
38598
|
-
"decoder.pullHandles": {
|
|
38599
|
-
capName: "decoder",
|
|
38600
|
-
capScope: "system",
|
|
38601
|
-
addonId: null,
|
|
38602
|
-
access: "view"
|
|
38603
|
-
},
|
|
38604
|
-
"decoder.pushPacket": {
|
|
38605
|
-
capName: "decoder",
|
|
38606
|
-
capScope: "system",
|
|
38607
|
-
addonId: null,
|
|
38608
|
-
access: "view"
|
|
38609
|
-
},
|
|
38610
38362
|
"decoder.reprobeHwaccel": {
|
|
38611
38363
|
capName: "decoder",
|
|
38612
38364
|
capScope: "system",
|
|
38613
38365
|
addonId: null,
|
|
38614
38366
|
access: "create"
|
|
38615
38367
|
},
|
|
38616
|
-
"decoder.supportsCodec": {
|
|
38617
|
-
capName: "decoder",
|
|
38618
|
-
capScope: "system",
|
|
38619
|
-
addonId: null,
|
|
38620
|
-
access: "view"
|
|
38621
|
-
},
|
|
38622
|
-
"decoder.updateConfig": {
|
|
38623
|
-
capName: "decoder",
|
|
38624
|
-
capScope: "system",
|
|
38625
|
-
addonId: null,
|
|
38626
|
-
access: "view"
|
|
38627
|
-
},
|
|
38628
38368
|
"detectionPipeline.applyDeviceSettingsPatch": {
|
|
38629
38369
|
capName: "detection-pipeline",
|
|
38630
38370
|
capScope: "device",
|
|
@@ -41715,12 +41455,6 @@ Object.freeze({
|
|
|
41715
41455
|
addonId: null,
|
|
41716
41456
|
access: "delete"
|
|
41717
41457
|
},
|
|
41718
|
-
"pipelineExecutor.deleteTemplate": {
|
|
41719
|
-
capName: "pipeline-executor",
|
|
41720
|
-
capScope: "system",
|
|
41721
|
-
addonId: null,
|
|
41722
|
-
access: "delete"
|
|
41723
|
-
},
|
|
41724
41458
|
"pipelineExecutor.downloadModel": {
|
|
41725
41459
|
capName: "pipeline-executor",
|
|
41726
41460
|
capScope: "system",
|
|
@@ -41859,12 +41593,6 @@ Object.freeze({
|
|
|
41859
41593
|
addonId: null,
|
|
41860
41594
|
access: "view"
|
|
41861
41595
|
},
|
|
41862
|
-
"pipelineExecutor.listTemplates": {
|
|
41863
|
-
capName: "pipeline-executor",
|
|
41864
|
-
capScope: "system",
|
|
41865
|
-
addonId: null,
|
|
41866
|
-
access: "view"
|
|
41867
|
-
},
|
|
41868
41596
|
"pipelineExecutor.rearmInferenceDevice": {
|
|
41869
41597
|
capName: "pipeline-executor",
|
|
41870
41598
|
capScope: "system",
|
|
@@ -41889,12 +41617,6 @@ Object.freeze({
|
|
|
41889
41617
|
addonId: null,
|
|
41890
41618
|
access: "create"
|
|
41891
41619
|
},
|
|
41892
|
-
"pipelineExecutor.saveTemplate": {
|
|
41893
|
-
capName: "pipeline-executor",
|
|
41894
|
-
capScope: "system",
|
|
41895
|
-
addonId: null,
|
|
41896
|
-
access: "create"
|
|
41897
|
-
},
|
|
41898
41620
|
"pipelineExecutor.setVideoPipelineSteps": {
|
|
41899
41621
|
capName: "pipeline-executor",
|
|
41900
41622
|
capScope: "system",
|
|
@@ -41913,12 +41635,6 @@ Object.freeze({
|
|
|
41913
41635
|
addonId: null,
|
|
41914
41636
|
access: "create"
|
|
41915
41637
|
},
|
|
41916
|
-
"pipelineExecutor.updateTemplate": {
|
|
41917
|
-
capName: "pipeline-executor",
|
|
41918
|
-
capScope: "system",
|
|
41919
|
-
addonId: null,
|
|
41920
|
-
access: "create"
|
|
41921
|
-
},
|
|
41922
41638
|
"pipelineExecutor.validatePipeline": {
|
|
41923
41639
|
capName: "pipeline-executor",
|
|
41924
41640
|
capScope: "system",
|
|
@@ -41949,12 +41665,6 @@ Object.freeze({
|
|
|
41949
41665
|
addonId: null,
|
|
41950
41666
|
access: "create"
|
|
41951
41667
|
},
|
|
41952
|
-
"pipelineOrchestrator.deleteTemplate": {
|
|
41953
|
-
capName: "pipeline-orchestrator",
|
|
41954
|
-
capScope: "system",
|
|
41955
|
-
addonId: null,
|
|
41956
|
-
access: "delete"
|
|
41957
|
-
},
|
|
41958
41668
|
"pipelineOrchestrator.getAgentLoad": {
|
|
41959
41669
|
capName: "pipeline-orchestrator",
|
|
41960
41670
|
capScope: "system",
|
|
@@ -42105,12 +41815,6 @@ Object.freeze({
|
|
|
42105
41815
|
addonId: null,
|
|
42106
41816
|
access: "view"
|
|
42107
41817
|
},
|
|
42108
|
-
"pipelineOrchestrator.listTemplates": {
|
|
42109
|
-
capName: "pipeline-orchestrator",
|
|
42110
|
-
capScope: "system",
|
|
42111
|
-
addonId: null,
|
|
42112
|
-
access: "view"
|
|
42113
|
-
},
|
|
42114
41818
|
"pipelineOrchestrator.pauseForStorageMigration": {
|
|
42115
41819
|
capName: "pipeline-orchestrator",
|
|
42116
41820
|
capScope: "system",
|
|
@@ -42165,12 +41869,6 @@ Object.freeze({
|
|
|
42165
41869
|
addonId: null,
|
|
42166
41870
|
access: "create"
|
|
42167
41871
|
},
|
|
42168
|
-
"pipelineOrchestrator.saveTemplate": {
|
|
42169
|
-
capName: "pipeline-orchestrator",
|
|
42170
|
-
capScope: "system",
|
|
42171
|
-
addonId: null,
|
|
42172
|
-
access: "create"
|
|
42173
|
-
},
|
|
42174
41872
|
"pipelineOrchestrator.setAgentCapabilities": {
|
|
42175
41873
|
capName: "pipeline-orchestrator",
|
|
42176
41874
|
capScope: "system",
|
|
@@ -42279,12 +41977,6 @@ Object.freeze({
|
|
|
42279
41977
|
addonId: null,
|
|
42280
41978
|
access: "create"
|
|
42281
41979
|
},
|
|
42282
|
-
"pipelineOrchestrator.updateTemplate": {
|
|
42283
|
-
capName: "pipeline-orchestrator",
|
|
42284
|
-
capScope: "system",
|
|
42285
|
-
addonId: null,
|
|
42286
|
-
access: "create"
|
|
42287
|
-
},
|
|
42288
41980
|
"pipelineRunner.attachCamera": {
|
|
42289
41981
|
capName: "pipeline-runner",
|
|
42290
41982
|
capScope: "system",
|
|
@@ -43719,12 +43411,6 @@ Object.freeze({
|
|
|
43719
43411
|
addonId: null,
|
|
43720
43412
|
access: "view"
|
|
43721
43413
|
},
|
|
43722
|
-
"streamBroker.pullFrameHandles": {
|
|
43723
|
-
capName: "stream-broker",
|
|
43724
|
-
capScope: "system",
|
|
43725
|
-
addonId: null,
|
|
43726
|
-
access: "view"
|
|
43727
|
-
},
|
|
43728
43414
|
"streamBroker.regenerateRtspToken": {
|
|
43729
43415
|
capName: "stream-broker",
|
|
43730
43416
|
capScope: "system",
|
|
@@ -43791,12 +43477,6 @@ Object.freeze({
|
|
|
43791
43477
|
addonId: null,
|
|
43792
43478
|
access: "create"
|
|
43793
43479
|
},
|
|
43794
|
-
"streamBroker.subscribeFrames": {
|
|
43795
|
-
capName: "stream-broker",
|
|
43796
|
-
capScope: "system",
|
|
43797
|
-
addonId: null,
|
|
43798
|
-
access: "create"
|
|
43799
|
-
},
|
|
43800
43480
|
"streamBroker.unassignProfile": {
|
|
43801
43481
|
capName: "stream-broker",
|
|
43802
43482
|
capScope: "system",
|
|
@@ -43809,12 +43489,6 @@ Object.freeze({
|
|
|
43809
43489
|
addonId: null,
|
|
43810
43490
|
access: "create"
|
|
43811
43491
|
},
|
|
43812
|
-
"streamBroker.unsubscribeFrames": {
|
|
43813
|
-
capName: "stream-broker",
|
|
43814
|
-
capScope: "system",
|
|
43815
|
-
addonId: null,
|
|
43816
|
-
access: "create"
|
|
43817
|
-
},
|
|
43818
43492
|
"streamCatalog.getCatalog": {
|
|
43819
43493
|
capName: "stream-catalog",
|
|
43820
43494
|
capScope: "device",
|
|
@@ -46328,11 +46002,6 @@ Object.freeze({
|
|
|
46328
46002
|
form: "single",
|
|
46329
46003
|
optional: false
|
|
46330
46004
|
}],
|
|
46331
|
-
"decoder.createSession": [{
|
|
46332
|
-
name: "deviceId",
|
|
46333
|
-
form: "single",
|
|
46334
|
-
optional: true
|
|
46335
|
-
}],
|
|
46336
46005
|
"detectionPipeline.applyDeviceSettingsPatch": [{
|
|
46337
46006
|
name: "deviceId",
|
|
46338
46007
|
form: "single",
|
|
@@ -50473,24 +50142,6 @@ var CAMERA_STREAM_CONTROLLER = {
|
|
|
50473
50142
|
audioCodecs: ["AAC"]
|
|
50474
50143
|
}]
|
|
50475
50144
|
};
|
|
50476
|
-
/**
|
|
50477
|
-
* `Alexa.EndpointHealth` — REQUIRED on a sensor endpoint (alexa-endpointhealth;
|
|
50478
|
-
* alexa-motionsensor: "Must also implement `Alexa.EndpointHealth`"), and every
|
|
50479
|
-
* camera endpoint may carry `Alexa.MotionSensor`. Declared on every camera so
|
|
50480
|
-
* Alexa can tell an offline camera from a broken one: `connectivity` comes
|
|
50481
|
-
* from the `device-status` cap in ReportState and is pushed as a ChangeReport
|
|
50482
|
-
* on `DeviceOnline` / `DeviceOffline` by the Event Gateway.
|
|
50483
|
-
*/
|
|
50484
|
-
var ENDPOINT_HEALTH = {
|
|
50485
|
-
type: "AlexaInterface",
|
|
50486
|
-
interface: "Alexa.EndpointHealth",
|
|
50487
|
-
version: "3",
|
|
50488
|
-
properties: {
|
|
50489
|
-
supported: [{ name: "connectivity" }],
|
|
50490
|
-
proactivelyReported: true,
|
|
50491
|
-
retrievable: true
|
|
50492
|
-
}
|
|
50493
|
-
};
|
|
50494
50145
|
var DOORBELL_EVENT_SOURCE = {
|
|
50495
50146
|
type: "AlexaInterface",
|
|
50496
50147
|
interface: "Alexa.DoorbellEventSource",
|
|
@@ -50653,6 +50304,27 @@ var PTZ_TILT_MODE_CONTROLLER = ptzDirectionalModeController("ptz.tilt", "Tilt",
|
|
|
50653
50304
|
label: "Down"
|
|
50654
50305
|
}
|
|
50655
50306
|
]);
|
|
50307
|
+
/** Amazon (alexa-modecontroller): "You must include a minimum of two mode
|
|
50308
|
+
* objects." One preset made the camera's whole AddOrUpdateReport fail
|
|
50309
|
+
* schema validation, and Discover dropped the camera. */
|
|
50310
|
+
var MIN_MODE_CONTROLLER_MODES = 2;
|
|
50311
|
+
/**
|
|
50312
|
+
* Preset names as distinct mode values. Two presets with the same name (the
|
|
50313
|
+
* camera allows it: `Stanza`, `Stanza`; `CamStack Home` ×3) produced two
|
|
50314
|
+
* identical modes, and Alexa rejected the capability — "Invalid capability
|
|
50315
|
+
* received." — and with it every endpoint of the camera. First wins,
|
|
50316
|
+
* case-insensitively: the SetMode handler resolves a value to the first
|
|
50317
|
+
* preset of that name, which is the one kept.
|
|
50318
|
+
*/
|
|
50319
|
+
function distinctPresetNames(names) {
|
|
50320
|
+
const seen = /* @__PURE__ */ new Set();
|
|
50321
|
+
return names.filter((name) => {
|
|
50322
|
+
const key = name.toLowerCase();
|
|
50323
|
+
if (seen.has(key)) return false;
|
|
50324
|
+
seen.add(key);
|
|
50325
|
+
return true;
|
|
50326
|
+
});
|
|
50327
|
+
}
|
|
50656
50328
|
function ptzPresetModeController(presetNames) {
|
|
50657
50329
|
return {
|
|
50658
50330
|
type: "AlexaInterface",
|
|
@@ -50692,13 +50364,13 @@ function buildParentCameraEndpoint(input) {
|
|
|
50692
50364
|
const capabilities = [
|
|
50693
50365
|
ALEXA_BASE_CAPABILITY,
|
|
50694
50366
|
CAMERA_STREAM_CONTROLLER,
|
|
50695
|
-
rtcSessionController(input.hasIntercom)
|
|
50696
|
-
ENDPOINT_HEALTH
|
|
50367
|
+
rtcSessionController(input.hasIntercom)
|
|
50697
50368
|
];
|
|
50698
50369
|
if (input.isDoorbell) capabilities.push(DOORBELL_EVENT_SOURCE);
|
|
50699
50370
|
if (input.hasMotion) capabilities.push(MOTION_SENSOR);
|
|
50700
50371
|
if (input.hasBattery) capabilities.push(BATTERY_LEVEL_SENSOR);
|
|
50701
|
-
|
|
50372
|
+
const presetNames = distinctPresetNames(input.ptzPresetNames);
|
|
50373
|
+
if (presetNames.length >= MIN_MODE_CONTROLLER_MODES) capabilities.push(ptzPresetModeController(presetNames));
|
|
50702
50374
|
if (input.hasPtz) {
|
|
50703
50375
|
capabilities.push(PTZ_PAN_MODE_CONTROLLER);
|
|
50704
50376
|
capabilities.push(PTZ_TILT_MODE_CONTROLLER);
|
|
@@ -50837,6 +50509,12 @@ function buildAlarmPanelEndpoint(input) {
|
|
|
50837
50509
|
};
|
|
50838
50510
|
}
|
|
50839
50511
|
//#endregion
|
|
50512
|
+
//#region src/handlers/ptz-preset-recallable.ts
|
|
50513
|
+
var RECALLABLE_FUNCTIONS = new Set(["home"]);
|
|
50514
|
+
function isAlexaRecallablePreset(preset) {
|
|
50515
|
+
return preset.fn === null || RECALLABLE_FUNCTIONS.has(preset.fn);
|
|
50516
|
+
}
|
|
50517
|
+
//#endregion
|
|
50840
50518
|
//#region src/handlers/discovery.ts
|
|
50841
50519
|
var discoveryPayloadSchema = DiscoveryDirectiveSchema.shape.payload;
|
|
50842
50520
|
/** Devices built at once in `handleDiscovery` — latency-bound tRPC reads, so
|
|
@@ -51024,7 +50702,7 @@ async function loadBoundDeviceInfo(device, api) {
|
|
|
51024
50702
|
};
|
|
51025
50703
|
}
|
|
51026
50704
|
async function fetchPtzPresetNames(deviceId, api) {
|
|
51027
|
-
return (await api.ptz.getPresets.query({ deviceId })).map((p) => p.name).filter((n) => n.length > 0);
|
|
50705
|
+
return (await api.ptz.getPresets.query({ deviceId })).filter(isAlexaRecallablePreset).map((p) => p.name).filter((n) => n.length > 0);
|
|
51028
50706
|
}
|
|
51029
50707
|
function classifyChildKind(deviceType, role) {
|
|
51030
50708
|
if (role === "floodlight" || role === "spotlight" || role === "nightvision") return "light";
|
|
@@ -51424,8 +51102,8 @@ async function handleSetMode(header, endpointRaw, payloadRaw, deps, _callerIdent
|
|
|
51424
51102
|
if (!mode.startsWith(PTZ_PRESET_MODE_PREFIX)) return errorEnvelope(header, "INVALID_DIRECTIVE", `mode '${mode}' is not a ptz.preset mode`);
|
|
51425
51103
|
const presetName = mode.slice(11);
|
|
51426
51104
|
if (presetName.length === 0) return errorEnvelope(header, "INVALID_DIRECTIVE", "preset name missing after prefix");
|
|
51427
|
-
const preset = (await api.ptz.getPresets.query({ deviceId: parsedId.deviceId })).find((p) => p.name === presetName);
|
|
51428
|
-
if (!preset) return errorEnvelope(header, "INVALID_DIRECTIVE", `preset '${presetName}' not
|
|
51105
|
+
const preset = (await api.ptz.getPresets.query({ deviceId: parsedId.deviceId })).find((p) => p.name === presetName && isAlexaRecallablePreset(p));
|
|
51106
|
+
if (!preset) return errorEnvelope(header, "INVALID_DIRECTIVE", `preset '${presetName}' is not a recallable preset on device ${parsedId.deviceId}`);
|
|
51429
51107
|
await api.ptz.goToPreset.mutate({
|
|
51430
51108
|
deviceId: parsedId.deviceId,
|
|
51431
51109
|
presetId: preset.id
|
|
@@ -51517,20 +51195,6 @@ async function collectCameraProperties(api, deviceId, properties, timeOfSample,
|
|
|
51517
51195
|
timeOfSample,
|
|
51518
51196
|
uncertaintyInMilliseconds: 0
|
|
51519
51197
|
});
|
|
51520
|
-
const online = boolField(await api.deviceStatus.getStatus.query({ deviceId }).catch((err) => {
|
|
51521
|
-
logger.warn("alexa report-state: deviceStatus.getStatus failed — connectivity omitted", {
|
|
51522
|
-
tags: { deviceId },
|
|
51523
|
-
meta: { error: err instanceof Error ? err.message : String(err) }
|
|
51524
|
-
});
|
|
51525
|
-
return null;
|
|
51526
|
-
}), "online");
|
|
51527
|
-
if (online !== null) properties.push({
|
|
51528
|
-
namespace: "Alexa.EndpointHealth",
|
|
51529
|
-
name: "connectivity",
|
|
51530
|
-
value: { value: online ? "OK" : "UNREACHABLE" },
|
|
51531
|
-
timeOfSample,
|
|
51532
|
-
uncertaintyInMilliseconds: 0
|
|
51533
|
-
});
|
|
51534
51198
|
const detected = boolField(await api.motion.getStatus.query({ deviceId }).catch((err) => {
|
|
51535
51199
|
logger.info("alexa report-state: motion.getStatus skipped", { meta: {
|
|
51536
51200
|
deviceId,
|
|
@@ -53487,7 +53151,7 @@ function buildAlexaOauthIntegration(publicHubUrl) {
|
|
|
53487
53151
|
* client id and SECRET, on the theory that a per-account refresh token was the
|
|
53488
53152
|
* real gate. The package is public on npm, so that secret was published with
|
|
53489
53153
|
* every version and has to be rotated. Since D753 the secret lives only in the
|
|
53490
|
-
* skill's Lambda (
|
|
53154
|
+
* skill's Lambda (SSM Parameter Store SecureString, D761); the hub gets short-lived Event Gateway
|
|
53491
53155
|
* tokens from the Lambda's broker (`broker-client.ts`) with a per-link
|
|
53492
53156
|
* credential. `scripts/check-no-client-secrets.ts` keeps it that way.
|
|
53493
53157
|
*
|
|
@@ -54518,7 +54182,7 @@ var ExportAlexaAddon = class extends BaseAddon {
|
|
|
54518
54182
|
content: [
|
|
54519
54183
|
"Public skill (default): enable the \"CamStack\" skill in the Alexa app and link your account — no Amazon developer setup is needed. A single published skill + hosted Lambda route to this hub using its public HTTPS URL (baked into every JWT).",
|
|
54520
54184
|
"The skill's Lambda keeps the Amazon credentials: this hub never holds an LWA client secret. It receives short-lived event tokens from the Lambda's token broker with a credential that is unique to this link.",
|
|
54521
|
-
"Custom skill: switch \"Alexa skill\" below to Custom, enter your skill id, and deploy the skill Lambda from this addon's lambda-template in your own AWS account (your LWA credentials go into
|
|
54185
|
+
"Custom skill: switch \"Alexa skill\" below to Custom, enter your skill id, and deploy the skill Lambda from this addon's lambda-template in your own AWS account (your LWA credentials go into SSM Parameter Store there, not here).",
|
|
54522
54186
|
"Either way this hub must be reachable from the public internet (Cloudflare Tunnel, Tailscale Funnel, …). The \"External address\" picker selects which detected endpoint the Lambda calls back on — press \"Refresh external addresses\" after setting up a new tunnel."
|
|
54523
54187
|
].join("\n")
|
|
54524
54188
|
},
|
|
@@ -54585,7 +54249,7 @@ var ExportAlexaAddon = class extends BaseAddon {
|
|
|
54585
54249
|
key: "__custom-skill-info",
|
|
54586
54250
|
label: "Your skill Lambda",
|
|
54587
54251
|
variant: "info",
|
|
54588
|
-
content: "Proactive events (doorbell, motion, battery, device-list updates) are authorised by YOUR skill Lambda: it keeps the \"Send Alexa Events\" LWA client id/secret in
|
|
54252
|
+
content: "Proactive events (doorbell, motion, battery, device-list updates) are authorised by YOUR skill Lambda: it keeps the \"Send Alexa Events\" LWA client id/secret in SSM Parameter Store and hands this hub short-lived tokens. Nothing to paste here — see the custom-skill setup guide."
|
|
54589
54253
|
}] : [{
|
|
54590
54254
|
type: "info",
|
|
54591
54255
|
key: "__public-skill-info",
|