@camstack/types 1.2.357 → 1.2.359

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.
@@ -723,6 +723,12 @@ export interface TopologyNode {
723
723
  * hub, offline rows, and when the hub cannot tell. Mirrors `TopologyNodeSchema`.
724
724
  */
725
725
  readonly meshTransport?: 'tls' | 'clear';
726
+ /**
727
+ * Whether the hub holds this online agent's capability registration.
728
+ * `false` = online but not ready. Absent for the hub and offline rows.
729
+ * Mirrors `TopologyNodeSchema`.
730
+ */
731
+ readonly capabilitiesRegistered?: boolean;
726
732
  }
727
733
  /**
728
734
  * Why a broker's stream health flipped — the discriminator that separates an
@@ -0,0 +1,121 @@
1
+ /**
2
+ * Retrain review — what an operator DID to the proposals a frame was offered.
3
+ *
4
+ * A training annotation used to keep only its final box. Whether the operator
5
+ * accepted a pipeline box as drawn, nudged it, relabelled it, deleted it or
6
+ * drew a new one was lost the moment Save was pressed — and that difference is
7
+ * the signal that says where the model is wrong. Each saved annotation now
8
+ * carries the `origin` snapshot it started from, and each frame carries the
9
+ * proposals the operator `dismissed`; this module is the ONE place that turns
10
+ * those facts into a per-box verdict, so the server (list answers), the MCP
11
+ * tools and the viewer all read the same classification.
12
+ *
13
+ * Pure, and free of runtime imports from the capability file (type imports are
14
+ * erased), so the viewer can take it from `@camstack/types/client`.
15
+ *
16
+ * ## Statuses
17
+ *
18
+ * - `added` — the operator drew it (no proposal behind it).
19
+ * - `removed` — a proposal the operator dismissed (a deletion is a fact).
20
+ * - `reclassified` — kept, but its class or label changed.
21
+ * - `adjusted` — kept, same class and label, but the rectangle moved.
22
+ * - `unchanged` — kept as proposed.
23
+ * - `model-error` — kept as a deliberate "do not detect here". NOT `removed`:
24
+ * a removed proposal teaches nothing, a model error teaches the detector a
25
+ * specific false positive. The two must never be counted together.
26
+ *
27
+ * ## Exact versus approximate
28
+ *
29
+ * A row saved with an `origin` is judged against that snapshot: exact. A row
30
+ * saved before origins existed has none; it is matched against the proposals
31
+ * the pipeline would draw now (exact bbox first, then best overlap) and every
32
+ * verdict reached that way is flagged `approximate`, because a re-derived
33
+ * proposal is not the one the operator saw.
34
+ */
35
+ import type { RetrainDismissed, RetrainOrigin } from './capabilities/pipeline-analytics.cap.js';
36
+ /** Every status, in the order a summary lists them. */
37
+ export declare const RETRAIN_REVIEW_STATUSES: readonly ['unchanged', 'adjusted', 'reclassified', 'added', 'removed', 'model-error'];
38
+ /** One of {@link RETRAIN_REVIEW_STATUSES} (the cap's `RetrainReviewStatus` is the same union). */
39
+ export type RetrainReviewStatusName = (typeof RETRAIN_REVIEW_STATUSES)[number];
40
+ /**
41
+ * Two boxes overlapping at least this much are the same subject when a legacy
42
+ * row (no origin) is matched against a proposal. Deliberately loose: a legacy
43
+ * row is judged on evidence that is no longer exact.
44
+ */
45
+ export declare const RETRAIN_REVIEW_MATCH_IOU = 0.5;
46
+ /**
47
+ * A kept box overlapping its origin at least this much is `unchanged`; below it
48
+ * the rectangle was moved or resized on purpose (`adjusted`). Not 1.0: the
49
+ * canvas rounds, and a box dragged by one pixel and dragged back is not an edit.
50
+ */
51
+ export declare const RETRAIN_REVIEW_ADJUSTED_IOU = 0.95;
52
+ /** The facts about a saved box the classification reads. */
53
+ export interface RetrainReviewSavedBox {
54
+ readonly id: string;
55
+ readonly bbox: RetrainOrigin['bbox'];
56
+ readonly macroClass: RetrainOrigin['macroClass'];
57
+ readonly label?: string;
58
+ readonly kind: 'subject' | 'model_error';
59
+ /** The snapshot the box started from; `null` on a pre-origin row. */
60
+ readonly origin: RetrainOrigin | null;
61
+ }
62
+ /** One verdict: a saved box, or a dismissed / vanished proposal. */
63
+ export interface RetrainReviewBox {
64
+ /** The saved row's id, or the proposal's ref for a `removed` verdict. */
65
+ readonly ref: string;
66
+ readonly savedId?: string;
67
+ readonly status: RetrainReviewStatusName;
68
+ /** `true` when the baseline was re-derived rather than snapshotted. */
69
+ readonly approximate: boolean;
70
+ /** The proposal this box was judged against, when there was one. */
71
+ readonly origin?: RetrainOrigin;
72
+ /** Overlap with that proposal, when both rectangles exist. */
73
+ readonly iou?: number;
74
+ }
75
+ export interface RetrainReview {
76
+ readonly boxes: readonly RetrainReviewBox[];
77
+ /** Any verdict in `boxes` is approximate. */
78
+ readonly approximate: boolean;
79
+ }
80
+ export interface RetrainReviewOptions {
81
+ /** Overlap that makes a legacy row and a proposal one subject. */
82
+ readonly matchIou?: number;
83
+ /** Overlap below which a kept box counts as `adjusted`. */
84
+ readonly adjustedIou?: number;
85
+ /**
86
+ * Treat a proposal nobody claimed as `removed` (approximate). Only for a
87
+ * frame whose rows predate origins: with exact data an unclaimed proposal is
88
+ * simply one the operator has not decided on yet, and must not be reported.
89
+ */
90
+ readonly inferRemoved?: boolean;
91
+ }
92
+ export interface RetrainReviewSummary {
93
+ readonly counts: Readonly<Record<RetrainReviewStatusName, number>>;
94
+ readonly total: number;
95
+ /** Verdicts other than `unchanged` — the frames worth a second look. */
96
+ readonly changed: number;
97
+ readonly approximate: boolean;
98
+ }
99
+ /** Intersection over union of two normalised rectangles. */
100
+ export declare function retrainBoxIou(a: RetrainOrigin['bbox'], b: RetrainOrigin['bbox']): number;
101
+ /**
102
+ * Classify what the operator did on ONE frame.
103
+ *
104
+ * @param saved the frame's saved boxes.
105
+ * @param origins the proposals known now (the pipeline's boxes, re-derived) —
106
+ * consulted ONLY for rows that carry no origin snapshot.
107
+ * @param dismissed the proposals the operator deleted, with their snapshots.
108
+ */
109
+ export declare function classifyRetrainReview(saved: readonly RetrainReviewSavedBox[], origins: readonly RetrainOrigin[], dismissed: readonly RetrainDismissed[], opts?: RetrainReviewOptions): RetrainReview;
110
+ /** Counts per status, plus the totals a list row shows. */
111
+ export declare function summarizeReview(review: RetrainReview): RetrainReviewSummary;
112
+ /** The prefix of the error a stale `expectedRevision` save is refused with. */
113
+ export declare const RETRAIN_REVISION_CONFLICT = "retrain-revision-conflict";
114
+ export interface RetrainRevisionConflict {
115
+ readonly currentRevision: number;
116
+ readonly expectedRevision: number;
117
+ }
118
+ /** The message a refused save carries — `parseRetrainRevisionConflict` reads it back. */
119
+ export declare function retrainRevisionConflictMessage(frameId: string, conflict: RetrainRevisionConflict): string;
120
+ /** The conflict an error message names, or `null` when it is some other error. */
121
+ export declare function parseRetrainRevisionConflict(message: string): RetrainRevisionConflict | null;
@@ -5131,6 +5131,7 @@ function createDeviceProxy(api, binding, opts) {
5131
5131
  proposeRetrainAnnotations: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "proposeRetrainAnnotations", "mutation", input),
5132
5132
  listRetrainAnnotations: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listRetrainAnnotations", "query", input),
5133
5133
  saveRetrainAnnotations: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "saveRetrainAnnotations", "mutation", input),
5134
+ backfillRetrainOrigins: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "backfillRetrainOrigins", "mutation", input),
5134
5135
  completeRetrainTrack: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "completeRetrainTrack", "mutation", input),
5135
5136
  restageRetrainTrack: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "restageRetrainTrack", "mutation", input),
5136
5137
  getRetrainExportUrl: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getRetrainExportUrl", "query", input),
@@ -5414,6 +5415,8 @@ function createDeviceProxy(api, binding, opts) {
5414
5415
  getAudioAssignment: (input) => dispatchSystem("pipelineOrchestrator", "getAudioAssignment", "query", input),
5415
5416
  getCameraSettings: (input) => dispatchSystem("pipelineOrchestrator", "getCameraSettings", "query", input),
5416
5417
  setCameraStepToggle: (input) => dispatchSystem("pipelineOrchestrator", "setCameraStepToggle", "mutation", input),
5418
+ getCameraDetectionSource: (input) => dispatchSystem("pipelineOrchestrator", "getCameraDetectionSource", "query", input),
5419
+ setCameraDetectionSource: (input) => dispatchSystem("pipelineOrchestrator", "setCameraDetectionSource", "mutation", input),
5417
5420
  getCameraStepOverrides: (input) => dispatchSystem("pipelineOrchestrator", "getCameraStepOverrides", "query", input),
5418
5421
  setCameraStepOverride: (input) => dispatchSystem("pipelineOrchestrator", "setCameraStepOverride", "mutation", input),
5419
5422
  setCameraStepSettings: (input) => dispatchSystem("pipelineOrchestrator", "setCameraStepSettings", "mutation", input),
@@ -5131,6 +5131,7 @@ function createDeviceProxy(api, binding, opts) {
5131
5131
  proposeRetrainAnnotations: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "proposeRetrainAnnotations", "mutation", input),
5132
5132
  listRetrainAnnotations: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "listRetrainAnnotations", "query", input),
5133
5133
  saveRetrainAnnotations: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "saveRetrainAnnotations", "mutation", input),
5134
+ backfillRetrainOrigins: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "backfillRetrainOrigins", "mutation", input),
5134
5135
  completeRetrainTrack: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "completeRetrainTrack", "mutation", input),
5135
5136
  restageRetrainTrack: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "restageRetrainTrack", "mutation", input),
5136
5137
  getRetrainExportUrl: (input) => dispatch("pipeline-analytics", "pipelineAnalytics", "getRetrainExportUrl", "query", input),
@@ -5414,6 +5415,8 @@ function createDeviceProxy(api, binding, opts) {
5414
5415
  getAudioAssignment: (input) => dispatchSystem("pipelineOrchestrator", "getAudioAssignment", "query", input),
5415
5416
  getCameraSettings: (input) => dispatchSystem("pipelineOrchestrator", "getCameraSettings", "query", input),
5416
5417
  setCameraStepToggle: (input) => dispatchSystem("pipelineOrchestrator", "setCameraStepToggle", "mutation", input),
5418
+ getCameraDetectionSource: (input) => dispatchSystem("pipelineOrchestrator", "getCameraDetectionSource", "query", input),
5419
+ setCameraDetectionSource: (input) => dispatchSystem("pipelineOrchestrator", "setCameraDetectionSource", "mutation", input),
5417
5420
  getCameraStepOverrides: (input) => dispatchSystem("pipelineOrchestrator", "getCameraStepOverrides", "query", input),
5418
5421
  setCameraStepOverride: (input) => dispatchSystem("pipelineOrchestrator", "setCameraStepOverride", "mutation", input),
5419
5422
  setCameraStepSettings: (input) => dispatchSystem("pipelineOrchestrator", "setCameraStepSettings", "mutation", input),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.2.357",
3
+ "version": "1.2.359",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",