@camstack/types 1.2.17 → 1.2.19
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 +2 -2
- package/dist/addon.mjs +2 -2
- package/dist/capabilities/addons.cap.d.ts +2 -2
- package/dist/capabilities/device-manager.cap.d.ts +22 -0
- package/dist/capabilities/index.d.ts +2 -2
- package/dist/capabilities/llm-runtime.cap.d.ts +3 -3
- package/dist/capabilities/llm.cap.d.ts +4 -4
- package/dist/capabilities/motion.cap.d.ts +13 -1
- package/dist/capabilities/notification-rules.cap.d.ts +142 -0
- package/dist/capabilities/pipeline-analytics.cap.d.ts +70 -1
- package/dist/capabilities/pipeline-executor.cap.d.ts +2 -2
- package/dist/capabilities/pipeline-orchestrator.cap.d.ts +6 -6
- package/dist/capabilities/recording-export.cap.d.ts +7 -7
- package/dist/capabilities/recording.cap.d.ts +1 -1
- package/dist/enums/event-category.d.ts +13 -0
- package/dist/enums.js +1 -1
- package/dist/enums.mjs +1 -1
- package/dist/{event-category-Cdyife4p.js → event-category-39bpf1r_.js} +13 -0
- package/dist/{event-category-BLcNejAE.mjs → event-category-Bz24uP1U.mjs} +13 -0
- package/dist/generated/addon-api.d.ts +7 -0
- package/dist/generated/method-access-map.d.ts +1 -1
- package/dist/generated/system-proxy.d.ts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +148 -5
- package/dist/index.mjs +145 -6
- package/dist/interfaces/addon.d.ts +10 -2
- package/dist/interfaces/readiness.d.ts +5 -1
- package/dist/interfaces/relocate.d.ts +2 -2
- package/dist/lifecycle/job.d.ts +2 -2
- package/dist/readiness/readiness-registry.d.ts +32 -2
- package/dist/{sleep-Ct4Is70g.mjs → sleep-BYyv9gUM.mjs} +31 -4
- package/dist/{sleep-yfPaamGa.js → sleep-mkNQLVPE.js} +31 -4
- package/dist/types/detection.d.ts +49 -1
- package/dist/types/engine-output.d.ts +19 -19
- package/dist/types/pipeline-step.d.ts +2 -2
- package/package.json +2 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_event_category = require("./event-category-
|
|
1
|
+
const require_event_category = require("./event-category-39bpf1r_.js");
|
|
2
2
|
let zod = require("zod");
|
|
3
3
|
//#region src/disposer-chain.ts
|
|
4
4
|
var DisposerChain = class {
|
|
@@ -1513,6 +1513,7 @@ var ReadinessRegistry = class {
|
|
|
1513
1513
|
logger;
|
|
1514
1514
|
now;
|
|
1515
1515
|
generation;
|
|
1516
|
+
verboseDeviceScopeLogs;
|
|
1516
1517
|
snapshot = /* @__PURE__ */ new Map();
|
|
1517
1518
|
subscriptions = /* @__PURE__ */ new Set();
|
|
1518
1519
|
unsubscribeBus;
|
|
@@ -1523,6 +1524,7 @@ var ReadinessRegistry = class {
|
|
|
1523
1524
|
this.logger = options.logger;
|
|
1524
1525
|
this.now = options.now ?? (() => Date.now());
|
|
1525
1526
|
this.generation = options.generation ?? randomGeneration();
|
|
1527
|
+
this.verboseDeviceScopeLogs = options.verboseDeviceScopeLogs ?? false;
|
|
1526
1528
|
this.unsubscribeBus = this.bus.subscribe({ category: "system.ready-state" }, (event) => this.ingest(event.data));
|
|
1527
1529
|
this.unsubscribeAgentOffline = this.bus.subscribe({ category: "agent.offline" }, (event) => this.synthesizeDownForNode(event.data.agentId));
|
|
1528
1530
|
if (typeof this.bus.getRecent === "function") try {
|
|
@@ -1576,9 +1578,16 @@ var ReadinessRegistry = class {
|
|
|
1576
1578
|
* Every applied entry dispatches a one-shot transition to matching
|
|
1577
1579
|
* subscriptions so pending `awaitReady` callers unblock without having
|
|
1578
1580
|
* to wait for a fresh event.
|
|
1581
|
+
*
|
|
1582
|
+
* Returns the number of records APPLIED (added or advanced). Callers
|
|
1583
|
+
* doing periodic reconciles use this to stay silent when the snapshot
|
|
1584
|
+
* changed nothing — the every-60s "hydrated 1446 record(s)" heartbeat
|
|
1585
|
+
* from every child process was pure noise (≈2 800 lines/hour observed
|
|
1586
|
+
* live on 2026-08-01).
|
|
1579
1587
|
*/
|
|
1580
1588
|
hydrate(records) {
|
|
1581
1589
|
const now = this.now();
|
|
1590
|
+
let applied = 0;
|
|
1582
1591
|
for (const record of records) {
|
|
1583
1592
|
const key = readinessKey(record.capName, record.scope);
|
|
1584
1593
|
const prev = this.snapshot.get(key) ?? null;
|
|
@@ -1604,7 +1613,8 @@ var ReadinessRegistry = class {
|
|
|
1604
1613
|
sourceNodeId: record.sourceNodeId
|
|
1605
1614
|
};
|
|
1606
1615
|
this.snapshot.set(key, hydrated);
|
|
1607
|
-
|
|
1616
|
+
applied++;
|
|
1617
|
+
this.logPerRecord(record.scope, `readiness: ${record.capName} (${scopeKey(record.scope)}) → ${record.state} (hydrated${prev !== null ? " update" : ""}, gen=${record.generation.slice(0, 6)})`);
|
|
1608
1618
|
const transition = {
|
|
1609
1619
|
capName: record.capName,
|
|
1610
1620
|
scope: record.scope,
|
|
@@ -1625,6 +1635,23 @@ var ReadinessRegistry = class {
|
|
|
1625
1635
|
}
|
|
1626
1636
|
}
|
|
1627
1637
|
}
|
|
1638
|
+
return applied;
|
|
1639
|
+
}
|
|
1640
|
+
/**
|
|
1641
|
+
* Per-record debug line, volume-gated: device-scoped records are logged
|
|
1642
|
+
* only when `verboseDeviceScopeLogs` is set (see the option's doc for
|
|
1643
|
+
* the 21 577-lines-per-boot-minute incident that forced the gate);
|
|
1644
|
+
* node/global records always log. Device lines carry `tags.deviceId`
|
|
1645
|
+
* so they group per-camera (CLAUDE.md logging rule).
|
|
1646
|
+
*/
|
|
1647
|
+
logPerRecord(scope, message) {
|
|
1648
|
+
if (!this.logger) return;
|
|
1649
|
+
if (scope.type === "device") {
|
|
1650
|
+
if (!this.verboseDeviceScopeLogs) return;
|
|
1651
|
+
this.logger.debug(message, { tags: { deviceId: scope.deviceId } });
|
|
1652
|
+
return;
|
|
1653
|
+
}
|
|
1654
|
+
this.logger.debug(message);
|
|
1628
1655
|
}
|
|
1629
1656
|
/**
|
|
1630
1657
|
* True when THIS process is the origin authority for `record` — a
|
|
@@ -1799,7 +1826,7 @@ var ReadinessRegistry = class {
|
|
|
1799
1826
|
ts: payload.ts,
|
|
1800
1827
|
durationInPrevState
|
|
1801
1828
|
};
|
|
1802
|
-
|
|
1829
|
+
this.logPerRecord(payload.scope, `readiness: ${payload.capName} (${scopeKey(payload.scope)}) → ${payload.state} epoch=${epoch} gen=${payload.generation.slice(0, 6)} (prev ${durationInPrevState}ms)`);
|
|
1803
1830
|
for (const sub of this.subscriptions) {
|
|
1804
1831
|
if (sub.capName !== payload.capName) continue;
|
|
1805
1832
|
if (!scopesEqual(sub.scope, payload.scope)) continue;
|
|
@@ -1844,7 +1871,7 @@ var ReadinessRegistry = class {
|
|
|
1844
1871
|
ts: now,
|
|
1845
1872
|
durationInPrevState
|
|
1846
1873
|
};
|
|
1847
|
-
|
|
1874
|
+
this.logPerRecord(record.scope, `readiness: ${record.capName} (${scopeKey(record.scope)}) → down (synthesized from agent.offline ${offlineNodeId})`);
|
|
1848
1875
|
for (const sub of this.subscriptions) {
|
|
1849
1876
|
if (sub.capName !== record.capName) continue;
|
|
1850
1877
|
if (!scopesEqual(sub.scope, record.scope)) continue;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BoundingBox as EngineBoundingBox,
|
|
1
|
+
import type { BoundingBox as EngineBoundingBox, FrameInput, Landmark } from './io.js';
|
|
2
2
|
export interface SpatialDetection {
|
|
3
3
|
readonly class: string;
|
|
4
4
|
readonly originalClass: string;
|
|
@@ -248,6 +248,47 @@ export interface AudioDetection extends DetectionBase {
|
|
|
248
248
|
* avoids an import-level collision.
|
|
249
249
|
*/
|
|
250
250
|
export type DetectionEntry = ObjectDetection | AudioDetection;
|
|
251
|
+
/**
|
|
252
|
+
* Why a POST-NMS box was dropped between the model and the overlay. One code
|
|
253
|
+
* per drop site — the diagnostic overlay shows the code verbatim, so a new
|
|
254
|
+
* drop site MUST add its own code here rather than reuse a neighbour's:
|
|
255
|
+
* - `class-filter`: class not in the step's `enabledMacroClasses`, or a
|
|
256
|
+
* COCO class the `classMap` does not map (both are class-identity drops
|
|
257
|
+
* and both count toward the trace's model-saw/kept gap).
|
|
258
|
+
* - `below-threshold`: score under the per-macro `minConfidence<Macro>`.
|
|
259
|
+
* - `full-frame-guard`: the full-frame phantom guard
|
|
260
|
+
* (`pipeline/full-frame-guard.ts`).
|
|
261
|
+
* - `zone-gate`: dropped by a detection-stage zone rule AFTER the frame
|
|
262
|
+
* result was built (`gateDetectionsByZoneRules`).
|
|
263
|
+
*
|
|
264
|
+
* NMS suppression is NOT a reason here: every engine's NMS runs in-process in
|
|
265
|
+
* the Python pool (`inference_pool.py` postprocessors) and the suppressed set
|
|
266
|
+
* is destroyed before the boundary — the trace's model-saw count is the only
|
|
267
|
+
* NMS visibility. A reason that can never fire does not belong in the union.
|
|
268
|
+
*/
|
|
269
|
+
export type DiscardReason = 'class-filter' | 'below-threshold' | 'full-frame-guard' | 'zone-gate';
|
|
270
|
+
/**
|
|
271
|
+
* A post-NMS box the pipeline dropped before it could reach the overlay /
|
|
272
|
+
* tracker / events — always carried on `FrameResult.discarded` when a frame
|
|
273
|
+
* drops at least one box (the discarded set is post-NMS and
|
|
274
|
+
* post-confidence-floor: a handful of boxes per frame, not the raw
|
|
275
|
+
* candidate flood, which never leaves the Python pool).
|
|
276
|
+
*
|
|
277
|
+
* `bbox` is the executor's `[x1, y1, x2, y2]` tuple in ABSOLUTE
|
|
278
|
+
* analysis-frame pixels (the same space the executor's drop sites hold) —
|
|
279
|
+
* consumers normalise against `FrameResult.width`/`height` from the same
|
|
280
|
+
* frame. Deliberately NOT the survivors' `{x, y, width, height}` object:
|
|
281
|
+
* the tuple is what every drop site already holds, and the viewer's
|
|
282
|
+
* `parseDiscardedEvent` accepts it as-is.
|
|
283
|
+
*/
|
|
284
|
+
export interface DiscardedDetection {
|
|
285
|
+
/** `[x1, y1, x2, y2]` in absolute analysis-frame pixels. */
|
|
286
|
+
readonly bbox: readonly [number, number, number, number];
|
|
287
|
+
/** Macro class where the classMap resolves one, else the raw model class. */
|
|
288
|
+
readonly macroClass: string;
|
|
289
|
+
readonly score: number;
|
|
290
|
+
readonly reason: DiscardReason;
|
|
291
|
+
}
|
|
251
292
|
/**
|
|
252
293
|
* Per-frame pipeline result — the canonical container emitted by
|
|
253
294
|
* `pipelineExecutor.runPipeline` (one-shot benchmark + runtime dispatch)
|
|
@@ -263,6 +304,13 @@ export interface FrameResult {
|
|
|
263
304
|
readonly width: number;
|
|
264
305
|
readonly height: number;
|
|
265
306
|
readonly detections: readonly ObjectDetection[];
|
|
307
|
+
/**
|
|
308
|
+
* Post-NMS boxes the pipeline dropped on this frame (see
|
|
309
|
+
* {@link DiscardedDetection}). Always populated when at least one box was
|
|
310
|
+
* dropped — absent means "nothing dropped", never "empty array". A frame
|
|
311
|
+
* that drops nothing allocates nothing and puts no field on the wire.
|
|
312
|
+
*/
|
|
313
|
+
readonly discarded?: readonly DiscardedDetection[];
|
|
266
314
|
readonly debug?: FrameDebug;
|
|
267
315
|
}
|
|
268
316
|
/**
|
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Output envelope of an inference engine call.
|
|
3
|
+
*
|
|
4
|
+
* Every engine is a Python pool (`inference_pool.py`) and postprocessing runs
|
|
5
|
+
* in-process there — the pool returns a `structured` StepOutput payload. The
|
|
6
|
+
* former Node.js onnxruntime raw-tensor fields (`tensor` / `tensors` /
|
|
7
|
+
* `letterbox`) were removed with that path: the platform ships no Node ONNX
|
|
8
|
+
* runtime.
|
|
9
|
+
*/
|
|
8
10
|
export interface EngineOutput {
|
|
9
|
-
readonly tensor?: Float32Array;
|
|
10
|
-
readonly tensors?: Record<string, Float32Array>;
|
|
11
11
|
readonly structured?: Record<string, unknown>;
|
|
12
|
-
readonly letterbox?: LetterboxMeta;
|
|
13
12
|
readonly inferenceMs: number;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
readonly
|
|
22
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Overload shed: the inference pool DELIBERATELY did not run inference for
|
|
15
|
+
* this frame (the Python pool's per-model in-flight bound, or the TS-side
|
|
16
|
+
* worker in-flight cap). A shed output carries NO `structured` payload —
|
|
17
|
+
* consumers skip the frame the way any dropped frame is skipped. It is an
|
|
18
|
+
* expected flow-control outcome, never an error.
|
|
19
|
+
*/
|
|
20
|
+
readonly dropped?: true;
|
|
21
|
+
/** Which bound shed the frame (e.g. `'worker-in-flight-cap'`). */
|
|
22
|
+
readonly shedReason?: string;
|
|
23
23
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ConfigField } from '../interfaces/config-ui.js';
|
|
2
2
|
import type { ClassMapDefinition } from './labels.js';
|
|
3
|
+
import type { ModelCatalogEntry } from './models.js';
|
|
3
4
|
import type { PipelineSlot } from './pipeline.js';
|
|
4
|
-
import type { ConfigField } from '../interfaces/config-ui.js';
|
|
5
5
|
/**
|
|
6
6
|
* Each pipeline step implements this interface as a class.
|
|
7
7
|
* `definition` holds the static metadata; `getConfigSchema()` declares
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/types",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.19",
|
|
4
4
|
"description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
},
|
|
49
49
|
"camstack": {
|
|
50
50
|
"system": false,
|
|
51
|
-
"displayName": "
|
|
51
|
+
"displayName": "Types",
|
|
52
52
|
"description": "Shared cap definitions, schemas, and runtime contracts. Required at server boot; updating restarts the hub."
|
|
53
53
|
},
|
|
54
54
|
"files": [
|