@camstack/types 1.1.32 → 1.1.34
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/addon.js +1 -1
- package/dist/addon.mjs +1 -1
- package/dist/capabilities/addons.cap.d.ts +1 -1
- package/dist/capabilities/alerts.cap.d.ts +5 -5
- package/dist/capabilities/camera-streams.cap.d.ts +5 -5
- package/dist/capabilities/cap-router-predicates.d.ts +32 -0
- package/dist/capabilities/capability-definition.d.ts +18 -13
- package/dist/capabilities/consumables.cap.d.ts +1 -1
- package/dist/capabilities/custom-model-registry.cap.d.ts +38 -0
- package/dist/capabilities/index.d.ts +8 -15
- package/dist/capabilities/integrations.cap.d.ts +1 -1
- package/dist/capabilities/model-convert.cap.d.ts +22 -3
- package/dist/capabilities/model-distributor.cap.d.ts +38 -0
- package/dist/capabilities/network-quality.cap.d.ts +1 -1
- package/dist/capabilities/nodes.cap.d.ts +1 -1
- package/dist/capabilities/pipeline-executor.cap.d.ts +161 -8
- package/dist/capabilities/pipeline-orchestrator.cap.d.ts +87 -44
- package/dist/capabilities/pipeline-runner.cap.d.ts +10 -69
- package/dist/capabilities/snapshot.cap.d.ts +3 -3
- package/dist/capabilities/stream-broker.cap.d.ts +9 -1
- package/dist/capabilities/system.cap.d.ts +1 -1
- package/dist/capabilities/toast.cap.d.ts +1 -1
- package/dist/capabilities/webrtc-session.cap.d.ts +15 -1
- package/dist/device/index.d.ts +2 -0
- package/dist/device/reachability-poll.d.ts +90 -0
- package/dist/encode-profile.d.ts +2 -2
- package/dist/enums/event-category.d.ts +12 -0
- package/dist/generated/addon-api.d.ts +771 -643
- package/dist/generated/capability-router-map.d.ts +4 -16
- package/dist/generated/device-proxy.d.ts +0 -2
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/system-proxy.d.ts +2 -2
- package/dist/index.d.ts +3 -3
- package/dist/index.js +568 -350
- package/dist/index.mjs +551 -344
- package/dist/interfaces/capability.d.ts +0 -7
- package/dist/interfaces/event-bus.d.ts +9 -0
- package/dist/interfaces/pipeline-executor-capability.d.ts +14 -1
- package/dist/interfaces/pipeline-runner-capability.d.ts +11 -11
- package/dist/interfaces/recording-config.d.ts +2 -2
- package/dist/{sleep-CZDdRBua.mjs → sleep-Cc14_yxc.mjs} +12 -4
- package/dist/{sleep-Dirr8nGw.js → sleep-DmP-uxoe.js} +12 -4
- package/dist/types/agent-pipeline-settings.d.ts +18 -6
- package/dist/types/camera-pipeline.d.ts +17 -3
- package/dist/types/model-variant-groups.d.ts +100 -0
- package/dist/types/models.d.ts +63 -3
- package/package.json +1 -1
- package/dist/capabilities/restreamer.cap.d.ts +0 -54
- package/dist/capabilities/snapshot-provider.cap.d.ts +0 -43
- package/dist/capabilities/streaming-engine.cap.d.ts +0 -61
- package/dist/capabilities/webrtc.cap.d.ts +0 -75
- package/dist/interfaces/restreamer.d.ts +0 -23
- package/dist/interfaces/streaming.d.ts +0 -28
- package/dist/interfaces/webrtc-provider.d.ts +0 -34
|
@@ -11,10 +11,7 @@ import type { ILogDestination } from './logging.js';
|
|
|
11
11
|
import type { IPipelineExecutorProvider } from './pipeline-executor-capability.js';
|
|
12
12
|
import type { IPipelineOrchestratorProvider } from './pipeline-orchestrator-capability.js';
|
|
13
13
|
import type { IPipelineRunnerProvider } from './pipeline-runner-capability.js';
|
|
14
|
-
import type { IRestreamer } from './restreamer.js';
|
|
15
14
|
import type { IEmbeddingsBackend, ISettingsBackend } from './storage.js';
|
|
16
|
-
import type { IStreamingEngine } from './streaming.js';
|
|
17
|
-
import type { IWebRtcProvider } from './webrtc-provider.js';
|
|
18
15
|
/**
|
|
19
16
|
* Pipeline step capability — each step is a separate capability
|
|
20
17
|
* named `pipeline-step:{stepId}` (e.g., `pipeline-step:object-detection`).
|
|
@@ -119,8 +116,6 @@ export interface CapabilityInfo {
|
|
|
119
116
|
export interface CapabilityProviderMap {
|
|
120
117
|
storage: InferProvider<typeof import('../capabilities/storage.cap.js').storageCapability>;
|
|
121
118
|
'log-destination': ILogDestination;
|
|
122
|
-
restreamer: IRestreamer;
|
|
123
|
-
webrtc: IWebRtcProvider;
|
|
124
119
|
'stream-broker': InferProvider<typeof streamBrokerCapability>;
|
|
125
120
|
'addon-pages': InferProvider<typeof import('../capabilities/addon-pages.cap.js').addonPagesCapability>;
|
|
126
121
|
'addon-pages-source': IAddonPageProvider;
|
|
@@ -143,7 +138,6 @@ export interface CapabilityProviderMap {
|
|
|
143
138
|
alerts: InferProvider<typeof import('../capabilities/alerts.cap.js').alertsCapability>;
|
|
144
139
|
backup: InferProvider<typeof import('../capabilities/backup.cap.js').backupCapability>;
|
|
145
140
|
'network-access': InferProvider<typeof import('../capabilities/network-access.cap.js').networkAccessCapability>;
|
|
146
|
-
'streaming-engine': IStreamingEngine;
|
|
147
141
|
'advanced-notifier': InferProvider<typeof import('../capabilities/advanced-notifier.cap.js').advancedNotifierCapability>;
|
|
148
142
|
'pipeline-executor': IPipelineExecutorProvider;
|
|
149
143
|
'detection-pipeline': InferProvider<typeof import('../capabilities/detection-pipeline.cap.js').detectionPipelineCapability>;
|
|
@@ -159,7 +153,6 @@ export interface CapabilityProviderMap {
|
|
|
159
153
|
'settings-store': ISettingsBackend;
|
|
160
154
|
embeddings: IEmbeddingsBackend;
|
|
161
155
|
snapshot: ISnapshotOrchestrator;
|
|
162
|
-
'snapshot-provider': InferProvider<typeof import('../capabilities/snapshot-provider.cap.js').snapshotProviderCapability>;
|
|
163
156
|
'metrics-provider': InferProvider<typeof import('../capabilities/metrics-provider.cap.js').metricsProviderCapability>;
|
|
164
157
|
'camera-streams': InferProvider<typeof import('../capabilities/camera-streams.cap.js').cameraStreamsCapability>;
|
|
165
158
|
'webrtc-session': InferProvider<typeof import('../capabilities/webrtc-session.cap.js').webrtcSessionCapability>;
|
|
@@ -662,6 +662,15 @@ export interface EventCatalog {
|
|
|
662
662
|
readonly deviceId: number;
|
|
663
663
|
readonly config: CameraPipelineConfig;
|
|
664
664
|
};
|
|
665
|
+
/**
|
|
666
|
+
* Cluster camera-source owner (`clusterRoles.ingestNode`) resolved/changed.
|
|
667
|
+
* Pushed by addon-pipeline-orchestrator on every node-capability refresh so
|
|
668
|
+
* the stream-broker gates physical-broker creation on the current owner
|
|
669
|
+
* without a per-`ensureBroker` `getIngestOwner` query.
|
|
670
|
+
*/
|
|
671
|
+
'pipeline.ingest-owner-changed': {
|
|
672
|
+
readonly ownerNodeId: string;
|
|
673
|
+
};
|
|
665
674
|
/**
|
|
666
675
|
* Periodic per-runner load snapshot (~1 Hz). Replaces UI polling on
|
|
667
676
|
* `pipelineRunner.getLocalLoad`. UI subscribes per agent node.
|
|
@@ -7,7 +7,7 @@ import type { FrameResult, DetectorOutput } from '../types/detection.js';
|
|
|
7
7
|
import type { ConfigUISchema } from './config-ui.js';
|
|
8
8
|
import type { InferenceCapabilities } from './inference-capabilities.js';
|
|
9
9
|
import type { IAddonResolver } from './pipeline-runner.js';
|
|
10
|
-
import type { EngineProvisioning } from '../capabilities/pipeline-executor.cap.js';
|
|
10
|
+
import type { EngineProvisioning, PipelineValidationResult } from '../capabilities/pipeline-executor.cap.js';
|
|
11
11
|
/**
|
|
12
12
|
* Step configuration for pipeline execution — no runtime/backend (comes
|
|
13
13
|
* from engine). Phase 7 (settings redesign) removed the generic
|
|
@@ -81,6 +81,19 @@ export interface IPipelineExecutorProvider {
|
|
|
81
81
|
getGlobalSteps(): Promise<PipelineDefaultStep[] | null>;
|
|
82
82
|
/** Get the runner-ready pipeline config */
|
|
83
83
|
getGlobalPipelineConfig(): Promise<PipelineConfig | null>;
|
|
84
|
+
/**
|
|
85
|
+
* Gate B (pre-init config-correctness gate). PURE COMPUTE against this
|
|
86
|
+
* node's `currentEngine.format` — resolves `steps` the same way the
|
|
87
|
+
* runtime dispatch path would and reports what WOULD happen, WITHOUT
|
|
88
|
+
* writing any node-global state (the node-default `modelSubstitutions`
|
|
89
|
+
* map stays owned exclusively by the node-default tree resolver).
|
|
90
|
+
* Called by the orchestrator at attach time, node-pinned to the target
|
|
91
|
+
* node, so config problems surface before `pipelineRunner.attachCamera`
|
|
92
|
+
* rather than at the first per-frame resolve. Never throws.
|
|
93
|
+
*/
|
|
94
|
+
validatePipeline(input: {
|
|
95
|
+
readonly steps: readonly PipelineStepInput[];
|
|
96
|
+
}): Promise<PipelineValidationResult>;
|
|
84
97
|
/** Get the currently selected engine (bootstrap default on the node). */
|
|
85
98
|
getSelectedEngine(): Promise<PipelineEngineChoice>;
|
|
86
99
|
/**
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { OrchestratorMetrics, CameraMetrics } from './api-shared.js';
|
|
2
|
-
import type { PipelineEngineChoice } from '../types/pipeline.js';
|
|
3
2
|
import type { PipelineStepInputOutput } from '../capabilities/pipeline-executor.cap.js';
|
|
4
3
|
import type { Zone } from '../capabilities/zones.cap.js';
|
|
5
4
|
import type { PipelinePhaseMode } from '../device/device-profile.js';
|
|
@@ -8,11 +7,10 @@ import type { PipelinePhaseMode } from '../device/device-profile.js';
|
|
|
8
7
|
* via `attachCamera`. Carries everything the runner needs to subscribe to
|
|
9
8
|
* the local stream-broker and dispatch frames to motion / detection caps.
|
|
10
9
|
*
|
|
11
|
-
* Stateless-pipeline model: `
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* absent content as "no inference" until Phase 3 makes them required.
|
|
10
|
+
* Stateless-pipeline model: `steps` and `audio` travel with the payload so
|
|
11
|
+
* the runner holds the content in RAM for the lifetime of the attach.
|
|
12
|
+
* Re-sent on rebalance, edit, or restart. Engine is NOT carried: it is
|
|
13
|
+
* node-local, resolved by the executing runner at dispatch time.
|
|
16
14
|
*/
|
|
17
15
|
export interface RunnerCameraConfig {
|
|
18
16
|
readonly deviceId: number;
|
|
@@ -24,14 +22,16 @@ export interface RunnerCameraConfig {
|
|
|
24
22
|
/** Motion sources that can activate the pipeline. At least one entry. */
|
|
25
23
|
readonly motionSources: import('../capabilities/pipeline-runner.cap.js').MotionSources;
|
|
26
24
|
readonly pipelineEnabled: boolean;
|
|
27
|
-
/** Engine choice for video steps — Phase 1 optional, runner ignores until Phase 3. */
|
|
28
|
-
readonly engine?: PipelineEngineChoice;
|
|
29
25
|
/** Ordered tree of video steps — Phase 1 optional, runner ignores until Phase 3. */
|
|
30
26
|
readonly steps?: readonly PipelineStepInputOutput[];
|
|
31
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* Audio classification branch — Phase 1 optional, runner ignores until
|
|
29
|
+
* Phase 3. `modelId` absent = model selection is data only; the
|
|
30
|
+
* executing node resolves its own format default at runtime
|
|
31
|
+
* (mirrors `CameraPipelineConfig.audio`).
|
|
32
|
+
*/
|
|
32
33
|
readonly audio?: {
|
|
33
|
-
readonly
|
|
34
|
-
readonly modelId: string;
|
|
34
|
+
readonly modelId?: string;
|
|
35
35
|
readonly enabled: boolean;
|
|
36
36
|
} | null;
|
|
37
37
|
/**
|
|
@@ -42,8 +42,8 @@ export declare const RecordingModeSchema: z.ZodEnum<{
|
|
|
42
42
|
}>;
|
|
43
43
|
export type RecordingMode = z.infer<typeof RecordingModeSchema>;
|
|
44
44
|
/**
|
|
45
|
-
* First-class, authoritative per-camera storage mode — the
|
|
46
|
-
* reads directly (never inferred from `rules`):
|
|
45
|
+
* First-class, authoritative per-camera storage mode — the explicit choice the
|
|
46
|
+
* UI reads directly (never inferred from `rules`):
|
|
47
47
|
* - `off` — not recording.
|
|
48
48
|
* - `events` — record only around triggers (motion / audio threshold),
|
|
49
49
|
* with pre/post-buffer.
|
|
@@ -250,6 +250,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
250
250
|
*/
|
|
251
251
|
EventCategory["PipelineCameraUpdated"] = "pipeline.camera-updated";
|
|
252
252
|
/**
|
|
253
|
+
* The cluster camera-source OWNER changed (`clusterRoles.ingestNode`).
|
|
254
|
+
* Emitted by addon-pipeline-orchestrator whenever it (re)derives node
|
|
255
|
+
* capabilities — at boot, on agent online/offline, and on an ingest-node
|
|
256
|
+
* flip. Carries the resolved `ownerNodeId`. The stream-broker consumes it to
|
|
257
|
+
* keep its ingest-owner-gate decision current WITHOUT a per-`ensureBroker`
|
|
258
|
+
* cross-process `getIngestOwner` query (push the authority's decision instead
|
|
259
|
+
* of polling it on the hot path). Idempotent state — re-emitted on every
|
|
260
|
+
* topology change, so a dropped event self-heals on the next one (plus the
|
|
261
|
+
* broker's long backstop reconcile query).
|
|
262
|
+
*/
|
|
263
|
+
EventCategory["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
|
|
264
|
+
/**
|
|
253
265
|
* Periodic snapshot of per-node pipeline-runner load
|
|
254
266
|
* (`RunnerLocalLoad`). Emitted ~1Hz by every runner so UI dashboards
|
|
255
267
|
* subscribe instead of polling `pipelineRunner.getLocalLoad`.
|
|
@@ -3566,10 +3578,6 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3566
3578
|
getDeviceLiveContribution: (input) => dispatchSystem("recording", "getDeviceLiveContribution", "query", input),
|
|
3567
3579
|
applyDeviceSettingsPatch: (input) => dispatchSystem("recording", "applyDeviceSettingsPatch", "mutation", input)
|
|
3568
3580
|
},
|
|
3569
|
-
snapshotProvider: {
|
|
3570
|
-
supportsDevice: (input) => dispatchSystem("snapshotProvider", "supportsDevice", "query", input),
|
|
3571
|
-
getSnapshot: (input) => dispatchSystem("snapshotProvider", "getSnapshot", "query", input)
|
|
3572
|
-
},
|
|
3573
3581
|
streamBroker: {
|
|
3574
3582
|
publishCameraStream: (input) => dispatchSystem("streamBroker", "publishCameraStream", "mutation", input),
|
|
3575
3583
|
retractCameraStream: (input) => dispatchSystem("streamBroker", "retractCameraStream", "mutation", input),
|
|
@@ -250,6 +250,18 @@ var EventCategory = /* @__PURE__ */ function(EventCategory) {
|
|
|
250
250
|
*/
|
|
251
251
|
EventCategory["PipelineCameraUpdated"] = "pipeline.camera-updated";
|
|
252
252
|
/**
|
|
253
|
+
* The cluster camera-source OWNER changed (`clusterRoles.ingestNode`).
|
|
254
|
+
* Emitted by addon-pipeline-orchestrator whenever it (re)derives node
|
|
255
|
+
* capabilities — at boot, on agent online/offline, and on an ingest-node
|
|
256
|
+
* flip. Carries the resolved `ownerNodeId`. The stream-broker consumes it to
|
|
257
|
+
* keep its ingest-owner-gate decision current WITHOUT a per-`ensureBroker`
|
|
258
|
+
* cross-process `getIngestOwner` query (push the authority's decision instead
|
|
259
|
+
* of polling it on the hot path). Idempotent state — re-emitted on every
|
|
260
|
+
* topology change, so a dropped event self-heals on the next one (plus the
|
|
261
|
+
* broker's long backstop reconcile query).
|
|
262
|
+
*/
|
|
263
|
+
EventCategory["PipelineIngestOwnerChanged"] = "pipeline.ingest-owner-changed";
|
|
264
|
+
/**
|
|
253
265
|
* Periodic snapshot of per-node pipeline-runner load
|
|
254
266
|
* (`RunnerLocalLoad`). Emitted ~1Hz by every runner so UI dashboards
|
|
255
267
|
* subscribe instead of polling `pipelineRunner.getLocalLoad`.
|
|
@@ -3566,10 +3578,6 @@ function createDeviceProxy(api, binding, opts) {
|
|
|
3566
3578
|
getDeviceLiveContribution: (input) => dispatchSystem("recording", "getDeviceLiveContribution", "query", input),
|
|
3567
3579
|
applyDeviceSettingsPatch: (input) => dispatchSystem("recording", "applyDeviceSettingsPatch", "mutation", input)
|
|
3568
3580
|
},
|
|
3569
|
-
snapshotProvider: {
|
|
3570
|
-
supportsDevice: (input) => dispatchSystem("snapshotProvider", "supportsDevice", "query", input),
|
|
3571
|
-
getSnapshot: (input) => dispatchSystem("snapshotProvider", "getSnapshot", "query", input)
|
|
3572
|
-
},
|
|
3573
3581
|
streamBroker: {
|
|
3574
3582
|
publishCameraStream: (input) => dispatchSystem("streamBroker", "publishCameraStream", "mutation", input),
|
|
3575
3583
|
retractCameraStream: (input) => dispatchSystem("streamBroker", "retractCameraStream", "mutation", input),
|
|
@@ -23,10 +23,14 @@ import type { CameraPipelineConfig } from './camera-pipeline.js';
|
|
|
23
23
|
* Every addon in the catalog gets one entry — whether enabled or not.
|
|
24
24
|
* Operators edit these to pick models, tune settings, flip default
|
|
25
25
|
* enabled state for their hardware.
|
|
26
|
+
*
|
|
27
|
+
* modelId present ONLY when the operator explicitly chose a model;
|
|
28
|
+
* absent = use this node's format default (resolved on-the-fly by the
|
|
29
|
+
* provider).
|
|
26
30
|
*/
|
|
27
31
|
export interface AgentAddonConfig {
|
|
28
32
|
readonly enabled: boolean;
|
|
29
|
-
readonly modelId
|
|
33
|
+
readonly modelId?: string;
|
|
30
34
|
readonly settings: Readonly<Record<string, unknown>>;
|
|
31
35
|
}
|
|
32
36
|
/**
|
|
@@ -48,9 +52,9 @@ export interface CameraStepOverridePatch {
|
|
|
48
52
|
* ownership moved to per-addon global settings (detection-pipeline,
|
|
49
53
|
* decoder-nodeav/ffmpeg, audio-analyzer). What's left on the
|
|
50
54
|
* orchestrator is the per-step defaults map (modelId / step settings)
|
|
51
|
-
* consumed by the resolver.
|
|
52
|
-
*
|
|
53
|
-
*
|
|
55
|
+
* consumed by the resolver. Engine is node-local — each executing node
|
|
56
|
+
* resolves its own format default at dispatch time; it is never stored
|
|
57
|
+
* on these settings nor carried on the attach payload.
|
|
54
58
|
*/
|
|
55
59
|
export interface AgentPipelineSettings {
|
|
56
60
|
readonly addonDefaults: Readonly<Record<string, AgentAddonConfig>>;
|
|
@@ -81,6 +85,13 @@ export interface AgentPipelineSettings {
|
|
|
81
85
|
readonly decode?: boolean;
|
|
82
86
|
readonly audio?: boolean;
|
|
83
87
|
readonly ingest?: boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Operator override for the LAN host a cross-node decoder dials to reach
|
|
90
|
+
* THIS node's restream (Cluster UI). Absent → auto-detect: a remote runner
|
|
91
|
+
* falls back to its `CAMSTACK_HUB_URL`-derived host. Set only when the
|
|
92
|
+
* auto-detected address is wrong (multi-homed host, NAT, custom interface).
|
|
93
|
+
*/
|
|
94
|
+
readonly reachableHost?: string;
|
|
84
95
|
}
|
|
85
96
|
/**
|
|
86
97
|
* Per-camera pipeline settings. Sparse by design — a camera that has
|
|
@@ -108,12 +119,13 @@ export interface CameraPipelineSettings {
|
|
|
108
119
|
* detection-pipeline addon's global settings. Operator picks steps
|
|
109
120
|
* + audio model/enabled only. This keeps the override portable
|
|
110
121
|
* across agent-moves and prevents a camera from being pinned to an
|
|
111
|
-
* engine the agent doesn't host.
|
|
122
|
+
* engine the agent doesn't host. `modelId` absent = data-only model
|
|
123
|
+
* selection — the executing node resolves its own format default.
|
|
112
124
|
*/
|
|
113
125
|
readonly pipelineByAgent?: Readonly<Record<string, {
|
|
114
126
|
readonly steps: CameraPipelineConfig['steps'];
|
|
115
127
|
readonly audio: {
|
|
116
|
-
readonly modelId
|
|
128
|
+
readonly modelId?: string;
|
|
117
129
|
readonly enabled: boolean;
|
|
118
130
|
} | null;
|
|
119
131
|
}>>;
|
|
@@ -23,11 +23,25 @@ import type { PipelineEngineChoice } from './pipeline.js';
|
|
|
23
23
|
* `audio-analyzer` not tied to this config.
|
|
24
24
|
*/
|
|
25
25
|
export interface CameraPipelineConfig {
|
|
26
|
-
|
|
26
|
+
/**
|
|
27
|
+
* Benchmark/template engine HINT ONLY — an explicit engine override the
|
|
28
|
+
* Image-Tester carries when saving a template. It is NEVER a live-dispatch
|
|
29
|
+
* field: the attach payload (`RunnerCameraConfig`) no longer carries an
|
|
30
|
+
* engine, so this value cannot reach a node. Engine is node-local — the
|
|
31
|
+
* executing runner resolves its own format default at dispatch time.
|
|
32
|
+
*/
|
|
33
|
+
readonly engine?: PipelineEngineChoice;
|
|
27
34
|
readonly steps: readonly PipelineStepInputOutput[];
|
|
28
35
|
readonly audio?: {
|
|
29
|
-
|
|
30
|
-
readonly
|
|
36
|
+
/** Benchmark/template engine hint only — see `engine` above. Not dispatched. */
|
|
37
|
+
readonly engine?: PipelineEngineChoice;
|
|
38
|
+
/**
|
|
39
|
+
* Present ONLY when the operator explicitly chose an audio model;
|
|
40
|
+
* absent = use this node's format default (resolved on-the-fly by
|
|
41
|
+
* the provider). Mirrors `AgentAddonConfig.modelId` (Task 4/5 of the
|
|
42
|
+
* engine-node-local refactor — model selection is data only).
|
|
43
|
+
*/
|
|
44
|
+
readonly modelId?: string;
|
|
31
45
|
readonly enabled: boolean;
|
|
32
46
|
/**
|
|
33
47
|
* Audio-classifier step settings (`enabledAudioClasses`,
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variant grouping for the model selector.
|
|
3
|
+
*
|
|
4
|
+
* The catalog is a FLAT list of `ModelCatalogEntry` (ids like `yolo26s`,
|
|
5
|
+
* `yolo26s-int8`) — that stays the source of truth for resolution, download and
|
|
6
|
+
* persistence. This module is a PRESENTATION overlay: it folds the flat list
|
|
7
|
+
* into a `family → tier → variant` tree so the UI can offer one grouped picker
|
|
8
|
+
* ("YOLO26" → "Small" → "Int8") instead of a flat dropdown of every
|
|
9
|
+
* size×quantization combination, and maps a grouped selection back to a flat
|
|
10
|
+
* model id.
|
|
11
|
+
*
|
|
12
|
+
* Only entries carrying `group` and NOT flagged `legacy` participate; legacy /
|
|
13
|
+
* ungrouped / custom models are never surfaced in the grouped selector (they
|
|
14
|
+
* stay reachable via the flat id when explicitly pinned).
|
|
15
|
+
*/
|
|
16
|
+
import type { ModelFormat } from './models.js';
|
|
17
|
+
export type VariantPrecision = 'fp32' | 'int8';
|
|
18
|
+
export type VariantOptimization = 'standard' | 'fast';
|
|
19
|
+
/**
|
|
20
|
+
* Minimal structural shape the grouped selector needs. Both the full
|
|
21
|
+
* `ModelCatalogEntry` (config UI) and the reduced `PipelineModelOption`
|
|
22
|
+
* (pipeline/device steppers) satisfy it, so one grouped picker serves every
|
|
23
|
+
* surface. `formats` is read only for "which formats ship" + a size hint, so a
|
|
24
|
+
* loose `{ sizeMB }`-per-key map covers both the catalog's rich format entries
|
|
25
|
+
* and the schema's `{ downloaded, sizeMB }` entries.
|
|
26
|
+
*/
|
|
27
|
+
export interface ModelVariantSource {
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly name: string;
|
|
30
|
+
readonly legacy?: boolean;
|
|
31
|
+
readonly group?: {
|
|
32
|
+
readonly family: string;
|
|
33
|
+
readonly tier: string;
|
|
34
|
+
readonly precision?: VariantPrecision;
|
|
35
|
+
readonly optimization?: VariantOptimization;
|
|
36
|
+
readonly resolution?: number;
|
|
37
|
+
};
|
|
38
|
+
readonly formats: Readonly<Record<string, {
|
|
39
|
+
readonly sizeMB: number;
|
|
40
|
+
} | undefined>>;
|
|
41
|
+
}
|
|
42
|
+
/** One selectable variant of a tier (a single flat catalog entry). */
|
|
43
|
+
export interface ModelVariantOption {
|
|
44
|
+
readonly modelId: string;
|
|
45
|
+
readonly precision: VariantPrecision;
|
|
46
|
+
readonly optimization: VariantOptimization;
|
|
47
|
+
/**
|
|
48
|
+
* Input resolution (square side, px). `undefined` ⇒ the family's native
|
|
49
|
+
* resolution (640 for yolo26). Reduced values (320 / 256) are the reduced-
|
|
50
|
+
* input latency variants.
|
|
51
|
+
*/
|
|
52
|
+
readonly resolution?: number;
|
|
53
|
+
/** Short chip label: `Standard` | `Int8` | `Fast` | `Fast · Int8`. */
|
|
54
|
+
readonly label: string;
|
|
55
|
+
/** Formats this variant ships (drives per-node availability). */
|
|
56
|
+
readonly formats: readonly ModelFormat[];
|
|
57
|
+
/** Smallest declared build size (MB) — a rough size hint for the chip. */
|
|
58
|
+
readonly sizeMB: number;
|
|
59
|
+
}
|
|
60
|
+
/** One size tier within a family (e.g. YOLO26 "Small"), with its variants. */
|
|
61
|
+
export interface ModelVariantTier {
|
|
62
|
+
readonly tier: string;
|
|
63
|
+
readonly label: string;
|
|
64
|
+
/** The fp32/standard base model id — the tier's canonical selection. */
|
|
65
|
+
readonly baseModelId: string;
|
|
66
|
+
readonly options: readonly ModelVariantOption[];
|
|
67
|
+
}
|
|
68
|
+
/** One model family (e.g. YOLO26), with its size tiers. */
|
|
69
|
+
export interface ModelVariantFamily {
|
|
70
|
+
readonly family: string;
|
|
71
|
+
readonly label: string;
|
|
72
|
+
readonly tiers: readonly ModelVariantTier[];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Fold a flat catalog into the `family → tier → variant` tree. Deterministic
|
|
76
|
+
* ordering: tiers by the canonical size ladder (unknown tiers appended
|
|
77
|
+
* alphabetically), variants standard-before-int8 and fast last.
|
|
78
|
+
*/
|
|
79
|
+
export declare function buildModelVariantGroups(models: readonly ModelVariantSource[]): readonly ModelVariantFamily[];
|
|
80
|
+
/**
|
|
81
|
+
* Map a grouped selection back to a flat catalog model id. Returns `null` when
|
|
82
|
+
* no entry matches (the UI then falls back to the tier base / format default).
|
|
83
|
+
* `precision`/`optimization` default to `fp32`/`standard` (the base build).
|
|
84
|
+
*/
|
|
85
|
+
export declare function resolveVariantModelId(models: readonly ModelVariantSource[], selection: {
|
|
86
|
+
readonly family: string;
|
|
87
|
+
readonly tier: string;
|
|
88
|
+
readonly precision?: VariantPrecision;
|
|
89
|
+
readonly optimization?: VariantOptimization;
|
|
90
|
+
/** `undefined` ⇒ the native-resolution build. */
|
|
91
|
+
readonly resolution?: number;
|
|
92
|
+
}): string | null;
|
|
93
|
+
/** Inverse: describe a flat model id as a grouped selection, or `null`. */
|
|
94
|
+
export declare function describeModelVariant(models: readonly ModelVariantSource[], modelId: string): {
|
|
95
|
+
readonly family: string;
|
|
96
|
+
readonly tier: string;
|
|
97
|
+
readonly precision: VariantPrecision;
|
|
98
|
+
readonly optimization: VariantOptimization;
|
|
99
|
+
readonly resolution?: number;
|
|
100
|
+
} | null;
|
package/dist/types/models.d.ts
CHANGED
|
@@ -94,6 +94,28 @@ export declare const ModelFormatsSchema: z.ZodObject<{
|
|
|
94
94
|
}>>>>;
|
|
95
95
|
}, z.core.$strip>>;
|
|
96
96
|
}, z.core.$strip>;
|
|
97
|
+
/**
|
|
98
|
+
* Variant-selector grouping axes. Shared by the full `ModelCatalogEntry` and by
|
|
99
|
+
* the reduced `PipelineModelOption` returned in `pipeline.getSchema()` so the
|
|
100
|
+
* grouped Family→Tier→Variant picker renders identically in the config UI and
|
|
101
|
+
* in the pipeline/device steppers. The flat `id` stays the source of truth for
|
|
102
|
+
* resolution/download/persistence; this is a presentation overlay resolved back
|
|
103
|
+
* to an `id`.
|
|
104
|
+
*/
|
|
105
|
+
export declare const ModelVariantGroupSchema: z.ZodObject<{
|
|
106
|
+
family: z.ZodString;
|
|
107
|
+
tier: z.ZodString;
|
|
108
|
+
precision: z.ZodOptional<z.ZodEnum<{
|
|
109
|
+
fp32: "fp32";
|
|
110
|
+
int8: "int8";
|
|
111
|
+
}>>;
|
|
112
|
+
optimization: z.ZodOptional<z.ZodEnum<{
|
|
113
|
+
standard: "standard";
|
|
114
|
+
fast: "fast";
|
|
115
|
+
}>>;
|
|
116
|
+
resolution: z.ZodOptional<z.ZodNumber>;
|
|
117
|
+
}, z.core.$strip>;
|
|
118
|
+
export type ModelVariantGroup = z.infer<typeof ModelVariantGroupSchema>;
|
|
97
119
|
export declare const ModelCatalogEntrySchema: z.ZodObject<{
|
|
98
120
|
id: z.ZodString;
|
|
99
121
|
name: z.ZodString;
|
|
@@ -180,6 +202,25 @@ export declare const ModelCatalogEntrySchema: z.ZodObject<{
|
|
|
180
202
|
filename: z.ZodString;
|
|
181
203
|
sizeMB: z.ZodNumber;
|
|
182
204
|
}, z.core.$strip>>>>;
|
|
205
|
+
legacy: z.ZodOptional<z.ZodBoolean>;
|
|
206
|
+
metrics: z.ZodOptional<z.ZodObject<{
|
|
207
|
+
map50: z.ZodOptional<z.ZodNumber>;
|
|
208
|
+
p95LatencyMs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
209
|
+
}, z.core.$strip>>;
|
|
210
|
+
license: z.ZodOptional<z.ZodString>;
|
|
211
|
+
group: z.ZodOptional<z.ZodObject<{
|
|
212
|
+
family: z.ZodString;
|
|
213
|
+
tier: z.ZodString;
|
|
214
|
+
precision: z.ZodOptional<z.ZodEnum<{
|
|
215
|
+
fp32: "fp32";
|
|
216
|
+
int8: "int8";
|
|
217
|
+
}>>;
|
|
218
|
+
optimization: z.ZodOptional<z.ZodEnum<{
|
|
219
|
+
standard: "standard";
|
|
220
|
+
fast: "fast";
|
|
221
|
+
}>>;
|
|
222
|
+
resolution: z.ZodOptional<z.ZodNumber>;
|
|
223
|
+
}, z.core.$strip>>;
|
|
183
224
|
}, z.core.$strip>;
|
|
184
225
|
export type ModelCatalogEntry = z.infer<typeof ModelCatalogEntrySchema>;
|
|
185
226
|
export interface DetectionModel {
|
|
@@ -219,8 +260,8 @@ export interface CustomModelMetadata {
|
|
|
219
260
|
export declare const ConvertTargetSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
220
261
|
format: z.ZodLiteral<"openvino">;
|
|
221
262
|
precisions: z.ZodReadonly<z.ZodArray<z.ZodEnum<{
|
|
222
|
-
fp16: "fp16";
|
|
223
263
|
int8: "int8";
|
|
264
|
+
fp16: "fp16";
|
|
224
265
|
}>>>;
|
|
225
266
|
}, z.core.$strip>, z.ZodObject<{
|
|
226
267
|
format: z.ZodLiteral<"coreml">;
|
|
@@ -273,8 +314,8 @@ export declare const ConvertArtifactSchema: z.ZodObject<{
|
|
|
273
314
|
pt: "pt";
|
|
274
315
|
}>;
|
|
275
316
|
precision: z.ZodOptional<z.ZodEnum<{
|
|
276
|
-
fp16: "fp16";
|
|
277
317
|
int8: "int8";
|
|
318
|
+
fp16: "fp16";
|
|
278
319
|
}>>;
|
|
279
320
|
sizeMB: z.ZodNumber;
|
|
280
321
|
validated: z.ZodBoolean;
|
|
@@ -368,6 +409,25 @@ export declare const ConvertResultSchema: z.ZodObject<{
|
|
|
368
409
|
filename: z.ZodString;
|
|
369
410
|
sizeMB: z.ZodNumber;
|
|
370
411
|
}, z.core.$strip>>>>;
|
|
412
|
+
legacy: z.ZodOptional<z.ZodBoolean>;
|
|
413
|
+
metrics: z.ZodOptional<z.ZodObject<{
|
|
414
|
+
map50: z.ZodOptional<z.ZodNumber>;
|
|
415
|
+
p95LatencyMs: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodNumber>>;
|
|
416
|
+
}, z.core.$strip>>;
|
|
417
|
+
license: z.ZodOptional<z.ZodString>;
|
|
418
|
+
group: z.ZodOptional<z.ZodObject<{
|
|
419
|
+
family: z.ZodString;
|
|
420
|
+
tier: z.ZodString;
|
|
421
|
+
precision: z.ZodOptional<z.ZodEnum<{
|
|
422
|
+
fp32: "fp32";
|
|
423
|
+
int8: "int8";
|
|
424
|
+
}>>;
|
|
425
|
+
optimization: z.ZodOptional<z.ZodEnum<{
|
|
426
|
+
standard: "standard";
|
|
427
|
+
fast: "fast";
|
|
428
|
+
}>>;
|
|
429
|
+
resolution: z.ZodOptional<z.ZodNumber>;
|
|
430
|
+
}, z.core.$strip>>;
|
|
371
431
|
}, z.core.$strip>;
|
|
372
432
|
artifacts: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
373
433
|
format: z.ZodEnum<{
|
|
@@ -378,8 +438,8 @@ export declare const ConvertResultSchema: z.ZodObject<{
|
|
|
378
438
|
pt: "pt";
|
|
379
439
|
}>;
|
|
380
440
|
precision: z.ZodOptional<z.ZodEnum<{
|
|
381
|
-
fp16: "fp16";
|
|
382
441
|
int8: "int8";
|
|
442
|
+
fp16: "fp16";
|
|
383
443
|
}>>;
|
|
384
444
|
sizeMB: z.ZodNumber;
|
|
385
445
|
validated: z.ZodBoolean;
|
package/package.json
CHANGED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { type InferProvider } from './capability-definition.js';
|
|
3
|
-
declare const RegisteredStreamSchema: z.ZodObject<{
|
|
4
|
-
streamId: z.ZodString;
|
|
5
|
-
label: z.ZodOptional<z.ZodString>;
|
|
6
|
-
codec: z.ZodString;
|
|
7
|
-
type: z.ZodEnum<{
|
|
8
|
-
audio: "audio";
|
|
9
|
-
video: "video";
|
|
10
|
-
}>;
|
|
11
|
-
sourceUrl: z.ZodString;
|
|
12
|
-
}, z.core.$strip>;
|
|
13
|
-
declare const ExposedResourceSchema: z.ZodObject<{
|
|
14
|
-
streamId: z.ZodString;
|
|
15
|
-
format: z.ZodString;
|
|
16
|
-
value: z.ZodString;
|
|
17
|
-
}, z.core.$strip>;
|
|
18
|
-
export declare const restreamerCapability: {
|
|
19
|
-
readonly name: "restreamer";
|
|
20
|
-
readonly scope: "system";
|
|
21
|
-
readonly mode: "collection";
|
|
22
|
-
readonly internal: true;
|
|
23
|
-
readonly methods: {
|
|
24
|
-
readonly registerDevice: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
25
|
-
deviceId: z.ZodNumber;
|
|
26
|
-
streams: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
27
|
-
streamId: z.ZodString;
|
|
28
|
-
label: z.ZodOptional<z.ZodString>;
|
|
29
|
-
codec: z.ZodString;
|
|
30
|
-
type: z.ZodEnum<{
|
|
31
|
-
audio: "audio";
|
|
32
|
-
video: "video";
|
|
33
|
-
}>;
|
|
34
|
-
sourceUrl: z.ZodString;
|
|
35
|
-
}, z.core.$strip>>>;
|
|
36
|
-
}, z.core.$strip>, z.ZodVoid, "mutation">;
|
|
37
|
-
readonly unregisterDevice: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
38
|
-
deviceId: z.ZodNumber;
|
|
39
|
-
}, z.core.$strip>, z.ZodVoid, "mutation">;
|
|
40
|
-
readonly getExposedResources: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
41
|
-
deviceId: z.ZodNumber;
|
|
42
|
-
}, z.core.$strip>, z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
43
|
-
streamId: z.ZodString;
|
|
44
|
-
format: z.ZodString;
|
|
45
|
-
value: z.ZodString;
|
|
46
|
-
}, z.core.$strip>>>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
47
|
-
};
|
|
48
|
-
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
49
|
-
readonly mount: {
|
|
50
|
-
readonly kind: "skip";
|
|
51
|
-
};
|
|
52
|
-
};
|
|
53
|
-
export type IRestreamerProvider = InferProvider<typeof restreamerCapability>;
|
|
54
|
-
export { RegisteredStreamSchema, ExposedResourceSchema };
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
import { type InferProvider } from './capability-definition.js';
|
|
3
|
-
/**
|
|
4
|
-
* snapshot-provider — collection of native snapshot implementations.
|
|
5
|
-
*
|
|
6
|
-
* Device provider addons (ONVIF, Frigate, etc.) register here
|
|
7
|
-
* when they can capture frames through a protocol-native path (e.g.
|
|
8
|
-
* ONVIF GetSnapshotUri, Frigate /api/<cam>/latest.jpg). The `snapshot`
|
|
9
|
-
* singleton orchestrator iterates over the collection, asking each
|
|
10
|
-
* provider whether it supports the requested device, and calls the
|
|
11
|
-
* first matching one.
|
|
12
|
-
*
|
|
13
|
-
* If no provider in the collection supports a device, the orchestrator
|
|
14
|
-
* falls back to `stream-broker.grabFrame` (universal fallback).
|
|
15
|
-
*
|
|
16
|
-
* Public tRPC router (auto-mounted) so out-of-process addons, agents,
|
|
17
|
-
* and advanced clients can bypass the orchestrator when needed.
|
|
18
|
-
*/
|
|
19
|
-
export declare const snapshotProviderCapability: {
|
|
20
|
-
readonly name: "snapshot-provider";
|
|
21
|
-
readonly scope: "system";
|
|
22
|
-
readonly mode: "collection";
|
|
23
|
-
readonly methods: {
|
|
24
|
-
readonly supportsDevice: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
25
|
-
deviceId: z.ZodNumber;
|
|
26
|
-
}, z.core.$strip>, z.ZodBoolean, import("./capability-definition.js").CapabilityMethodKind>;
|
|
27
|
-
readonly getSnapshot: import("./capability-definition.js").CapabilityMethodSchema<z.ZodObject<{
|
|
28
|
-
deviceId: z.ZodNumber;
|
|
29
|
-
streamId: z.ZodOptional<z.ZodString>;
|
|
30
|
-
}, z.core.$strip>, z.ZodNullable<z.ZodObject<{
|
|
31
|
-
base64: z.ZodString;
|
|
32
|
-
contentType: z.ZodString;
|
|
33
|
-
}, z.core.$strip>>, import("./capability-definition.js").CapabilityMethodKind>;
|
|
34
|
-
};
|
|
35
|
-
/** BIG PLAN 2: declarative mount hint — read by `@camstack/system` `buildCapRouters`. */
|
|
36
|
-
readonly mount: {
|
|
37
|
-
readonly kind: "custom";
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
export type ISnapshotProvider = InferProvider<typeof snapshotProviderCapability> & {
|
|
41
|
-
readonly id: string;
|
|
42
|
-
readonly name: string;
|
|
43
|
-
};
|