@camstack/system 1.2.52 → 1.2.54

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.
Files changed (54) hide show
  1. package/dist/addon-runner.js +1 -1
  2. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  3. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  4. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  5. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  6. package/dist/builtins/alerts/alerts.addon.js +1 -1
  7. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  8. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +1 -1
  9. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +1 -1
  10. package/dist/builtins/console-logging/index.js +1 -1
  11. package/dist/builtins/console-logging/index.mjs +1 -1
  12. package/dist/builtins/core-blocks/core-blocks.addon.js +1 -1
  13. package/dist/builtins/core-blocks/core-blocks.addon.mjs +1 -1
  14. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  15. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  16. package/dist/builtins/doorbell/virtual-doorbell.addon.js +1 -1
  17. package/dist/builtins/doorbell/virtual-doorbell.addon.mjs +1 -1
  18. package/dist/builtins/hub-forwarder/index.js +1 -1
  19. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  20. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  21. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  22. package/dist/builtins/local-auth/local-auth.addon.js +1 -1
  23. package/dist/builtins/local-auth/local-auth.addon.mjs +1 -1
  24. package/dist/builtins/local-network/local-network.addon.js +1 -1
  25. package/dist/builtins/local-network/local-network.addon.mjs +1 -1
  26. package/dist/builtins/loki-logging/index.js +1 -1
  27. package/dist/builtins/loki-logging/index.mjs +1 -1
  28. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  29. package/dist/builtins/native-metrics/native-metrics.addon.mjs +1 -1
  30. package/dist/builtins/platform-probe/index.js +1 -1
  31. package/dist/builtins/platform-probe/index.mjs +1 -1
  32. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  33. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  34. package/dist/builtins/snapshot/index.js +1 -1
  35. package/dist/builtins/snapshot/index.mjs +1 -1
  36. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  37. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  38. package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +17 -2
  39. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +246 -409
  40. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +246 -409
  41. package/dist/builtins/sqlite-storage/vector-index-shared.d.ts +47 -0
  42. package/dist/builtins/sqlite-storage/vector-index-vec.d.ts +55 -0
  43. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  44. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  45. package/dist/builtins/system-config/system-config.addon.js +1 -1
  46. package/dist/builtins/system-config/system-config.addon.mjs +1 -1
  47. package/dist/builtins/winston-logging/index.js +1 -1
  48. package/dist/builtins/winston-logging/index.mjs +1 -1
  49. package/dist/{dist-C-I9UG-Y.mjs → dist-BOpRqInW.mjs} +32 -21
  50. package/dist/{dist-DHU3Uq9p.js → dist-CblJsHb-.js} +31 -26
  51. package/dist/index.js +1 -1
  52. package/dist/index.mjs +1 -1
  53. package/package.json +3 -2
  54. package/dist/builtins/sqlite-storage/vector-index.d.ts +0 -197
@@ -0,0 +1,47 @@
1
+ import { VectorFilter, VectorMetadata, VectorMetric } from '@camstack/types';
2
+ /** Metadata keys promoted to real, indexable columns in every backend. */
3
+ export declare const PROMOTED_COLUMNS: readonly ["deviceId", "timestamp", "className", "modelId"];
4
+ /** A ranked hit as a backend returns it. */
5
+ export interface VectorMatchRow {
6
+ readonly id: string;
7
+ /** Similarity, higher is nearer — NOT a distance. Backends convert. */
8
+ readonly score: number;
9
+ readonly metadata: VectorMetadata;
10
+ }
11
+ export interface VectorIndexStats {
12
+ readonly backend: string;
13
+ readonly count: number;
14
+ readonly dim: number;
15
+ readonly metric: VectorMetric;
16
+ readonly exact: boolean;
17
+ }
18
+ export interface VectorIndexBackend {
19
+ loadIndexRegistry(): Promise<void>;
20
+ declareIndex(index: string, dim: number, metric: VectorMetric): Promise<void>;
21
+ upsert(index: string, items: readonly {
22
+ id: string;
23
+ vector: string;
24
+ metadata: VectorMetadata;
25
+ }[]): Promise<{
26
+ upserted: number;
27
+ rejected: number;
28
+ }>;
29
+ query(params: {
30
+ index: string;
31
+ vector: string;
32
+ topK: number;
33
+ minScore?: number;
34
+ filter?: VectorFilter;
35
+ }): Promise<{
36
+ matches: VectorMatchRow[];
37
+ scanned: number;
38
+ truncated: boolean;
39
+ }>;
40
+ getByIds(index: string, ids: readonly string[]): Promise<Array<{
41
+ id: string;
42
+ metadata: VectorMetadata;
43
+ }>>;
44
+ deleteByIds(index: string, ids: readonly string[]): Promise<number>;
45
+ deleteByFilter(index: string, filter: VectorFilter): Promise<number>;
46
+ stats(index: string): Promise<VectorIndexStats>;
47
+ }
@@ -0,0 +1,55 @@
1
+ import { IScopedLogger, VectorFilter, VectorMetadata, VectorMetric, encodeVectorBase64 } from '@camstack/types';
2
+ import { VectorIndexStats, VectorMatchRow } from './vector-index-shared.js';
3
+ /** The raw statement surface this index needs from better-sqlite3. */
4
+ export interface RawSqliteDatabase {
5
+ exec(sql: string): unknown;
6
+ prepare(sql: string): {
7
+ run(...params: unknown[]): {
8
+ changes: number;
9
+ };
10
+ all(...params: unknown[]): unknown[];
11
+ get(...params: unknown[]): unknown;
12
+ };
13
+ loadExtension?(path: string): void;
14
+ }
15
+ export interface SqliteVecIndexDeps {
16
+ readonly db: RawSqliteDatabase;
17
+ readonly logger: IScopedLogger;
18
+ }
19
+ export declare class SqliteVecVectorIndex {
20
+ private readonly db;
21
+ private readonly logger;
22
+ private readonly specs;
23
+ constructor(deps: SqliteVecIndexDeps);
24
+ /** Recover index declarations so an existing table is usable from boot. */
25
+ loadIndexRegistry(): Promise<void>;
26
+ declareIndex(index: string, dim: number, metric: VectorMetric): Promise<void>;
27
+ private specOf;
28
+ upsert(index: string, items: readonly {
29
+ id: string;
30
+ vector: string;
31
+ metadata: VectorMetadata;
32
+ }[]): Promise<{
33
+ upserted: number;
34
+ rejected: number;
35
+ }>;
36
+ query(params: {
37
+ index: string;
38
+ vector: string;
39
+ topK: number;
40
+ minScore?: number;
41
+ filter?: VectorFilter;
42
+ }): Promise<{
43
+ matches: VectorMatchRow[];
44
+ scanned: number;
45
+ truncated: boolean;
46
+ }>;
47
+ getByIds(index: string, ids: readonly string[]): Promise<Array<{
48
+ id: string;
49
+ metadata: VectorMetadata;
50
+ }>>;
51
+ deleteByIds(index: string, ids: readonly string[]): Promise<number>;
52
+ deleteByFilter(index: string, filter: VectorFilter): Promise<number>;
53
+ stats(index: string): Promise<VectorIndexStats>;
54
+ }
55
+ export { encodeVectorBase64 };
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-DHU3Uq9p.js");
6
+ const require_dist = require("../../dist-CblJsHb-.js");
7
7
  let node_path = require("node:path");
8
8
  node_path = require_chunk.__toESM(node_path);
9
9
  let node_fs_promises = require("node:fs/promises");
@@ -1,4 +1,4 @@
1
- import { Mt as parseJsonObject, f as StorageLocationTypeSchema, ft as BaseAddon, rt as storageCapability, tt as settingsStoreCapability } from "../../dist-C-I9UG-Y.mjs";
1
+ import { dt as BaseAddon, et as settingsStoreCapability, f as StorageLocationTypeSchema, jt as parseJsonObject, nt as storageCapability } from "../../dist-BOpRqInW.mjs";
2
2
  import * as path$1 from "node:path";
3
3
  import * as fs from "node:fs/promises";
4
4
  import { buildStorageLocationRegistry } from "@camstack/system";
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-DHU3Uq9p.js");
6
+ const require_dist = require("../../dist-CblJsHb-.js");
7
7
  //#region src/builtins/system-config/system-config.addon.ts
8
8
  /**
9
9
  * Built-in `system-config` addon — Phase 4 of the settings redesign.
@@ -1,4 +1,4 @@
1
- import { dt as errMsg, ft as BaseAddon, kt as hydrateSchema } from "../../dist-C-I9UG-Y.mjs";
1
+ import { Ot as hydrateSchema, dt as BaseAddon, ut as errMsg } from "../../dist-BOpRqInW.mjs";
2
2
  //#region src/builtins/system-config/system-config.addon.ts
3
3
  /**
4
4
  * Built-in `system-config` addon — Phase 4 of the settings redesign.
@@ -3,7 +3,7 @@ Object.defineProperties(exports, {
3
3
  [Symbol.toStringTag]: { value: "Module" }
4
4
  });
5
5
  const require_chunk = require("../../chunk-Cek0wNdY.js");
6
- const require_dist = require("../../dist-DHU3Uq9p.js");
6
+ const require_dist = require("../../dist-CblJsHb-.js");
7
7
  const require_formatter = require("../../formatter-DqAKDlvN.js");
8
8
  let node_path = require("node:path");
9
9
  node_path = require_chunk.__toESM(node_path);
@@ -1,4 +1,4 @@
1
- import { W as logDestinationCapability, ft as BaseAddon } from "../../dist-C-I9UG-Y.mjs";
1
+ import { U as logDestinationCapability, dt as BaseAddon } from "../../dist-BOpRqInW.mjs";
2
2
  import { t as formatLogLine } from "../../formatter-B7qW8bPJ.mjs";
3
3
  import * as path$1 from "node:path";
4
4
  import path from "node:path";
@@ -12845,7 +12845,22 @@ var RebuildObjectEmbeddingsInput = z.object({
12845
12845
  * means the same thing.
12846
12846
  */
12847
12847
  var WipeObjectEmbeddingsResultSchema = z.object({ deleted: z.number() });
12848
+ /**
12849
+ * Acknowledgement that a rebuild STARTED.
12850
+ *
12851
+ * The pass costs ~1s per track — 45 minutes for a 2,600-track fleet — so it
12852
+ * runs detached and this returns immediately. Waiting for it made the client
12853
+ * time out while the work carried on server-side, which is the worst of both:
12854
+ * no result and no way to know it was still going. Poll
12855
+ * `getObjectEmbeddingRebuildStatus` for progress.
12856
+ */
12848
12857
  var RebuildObjectEmbeddingsResultSchema = z.object({
12858
+ started: z.boolean(),
12859
+ /** True when a pass was already running; the new request is ignored. */
12860
+ alreadyRunning: z.boolean()
12861
+ });
12862
+ var RebuildStatusSchema = z.object({
12863
+ running: z.boolean(),
12849
12864
  scanned: z.number(),
12850
12865
  rebuilt: z.number(),
12851
12866
  /** Tracks whose key frame is gone — nothing to re-embed from. */
@@ -12853,8 +12868,12 @@ var RebuildObjectEmbeddingsResultSchema = z.object({
12853
12868
  /** Tracks with no usable detection box. */
12854
12869
  missingBbox: z.number(),
12855
12870
  failed: z.number(),
12856
- /** False when the pass stopped at `maxTracks` with tracks left. */
12857
- complete: z.boolean()
12871
+ /** Set once a pass ends: true only when EVERYTHING was covered. */
12872
+ complete: z.boolean().nullable(),
12873
+ startedAtMs: z.number().nullable(),
12874
+ finishedAtMs: z.number().nullable(),
12875
+ /** Present when the pass ended by throwing. */
12876
+ error: z.string().nullable()
12858
12877
  });
12859
12878
  var pipelineAnalyticsCapability = {
12860
12879
  name: "pipeline-analytics",
@@ -13129,15 +13148,15 @@ var pipelineAnalyticsCapability = {
13129
13148
  * `minScore`, sorted descending by score.
13130
13149
  */
13131
13150
  searchObjectEvents: method(SearchObjectEventsInput, z.array(ScoredObjectEventSchema).readonly()),
13132
- wipeObjectEmbeddings: method(z.void(), WipeObjectEmbeddingsResultSchema, {
13151
+ wipeObjectEmbeddings: method(z.object({}), WipeObjectEmbeddingsResultSchema, {
13133
13152
  kind: "mutation",
13134
13153
  auth: "admin"
13135
13154
  }),
13136
13155
  rebuildObjectEmbeddings: method(RebuildObjectEmbeddingsInput, RebuildObjectEmbeddingsResultSchema, {
13137
13156
  kind: "mutation",
13138
- auth: "admin",
13139
- timeoutMs: 30 * 6e4
13140
- })
13157
+ auth: "admin"
13158
+ }),
13159
+ getObjectEmbeddingRebuildStatus: method(z.object({}), RebuildStatusSchema)
13141
13160
  },
13142
13161
  events: {
13143
13162
  /**
@@ -27956,6 +27975,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
27956
27975
  addonId: null,
27957
27976
  access: "view"
27958
27977
  },
27978
+ "pipelineAnalytics.getObjectEmbeddingRebuildStatus": {
27979
+ capName: "pipeline-analytics",
27980
+ capScope: "device",
27981
+ addonId: null,
27982
+ access: "view"
27983
+ },
27959
27984
  "pipelineAnalytics.getObjectEvents": {
27960
27985
  capName: "pipeline-analytics",
27961
27986
  capScope: "device",
@@ -30264,20 +30289,6 @@ TimelapseRuleInputSchema.extend({
30264
30289
  createdAt: z.number(),
30265
30290
  updatedAt: z.number()
30266
30291
  });
30267
- /** Cosine similarity between two embedding vectors */
30268
- function cosineSimilarity(a, b) {
30269
- if (a.length !== b.length) return 0;
30270
- let dotProduct = 0;
30271
- let normA = 0;
30272
- let normB = 0;
30273
- for (let i = 0; i < a.length; i++) {
30274
- dotProduct += a[i] * b[i];
30275
- normA += a[i] * a[i];
30276
- normB += b[i] * b[i];
30277
- }
30278
- const denom = Math.sqrt(normA) * Math.sqrt(normB);
30279
- return denom === 0 ? 0 : dotProduct / denom;
30280
- }
30281
30292
  /**
30282
30293
  * Decode base64 little-endian Float32 back into a vector.
30283
30294
  *
@@ -30410,4 +30421,4 @@ function enumerateInferenceDevices(hw) {
30410
30421
  return out;
30411
30422
  }
30412
30423
  //#endregion
30413
- export { scoreRuntimes as $, enumerateInferenceDevices as A, isDeviceConfigCap as At, isVoidInput as B, cosineSimilarity as C, asNumber as Ct, deviceStateCapability as D, emitReadiness as Dt, deviceManagerCapability as E, emitDownForOwnedCaps as Et, filesystemBrowseCapability as F, resolveCapMount as Ft, logLevelAtMost as G, lifecycleJobSchema as H, getByPath as I, scopeKey as It, normalizeUnit as J, looseSchema as K, isArrayOutputSchema as L, sleep as Lt, enumerateSchemaFields as M, parseJsonObject as Mt, evaluateLinkExpression as N, parseJsonUnknown as Nt, deviceStatusCapability as O, expandCapMethods as Ot, extractNestedAddonId as P, readinessKey as Pt, procedureAuthKey as Q, isCollectionArrayMethod as R, EventCategory as Rt, coreBlocksCapability as S, asJsonObject as St, decodeVectorBase64 as T, createEvent as Tt, localNetworkCapability as U, kebabToCamel as V, logDestinationCapability as W, parseStreamParamsFormPatch as X, objectInputDeclaresAddonId as Y, platformProbeCapability as Z, alertsCapability as _, DeviceRole as _t, CAP_NAMES_WITH_STATUS as a, streamQualityLabel as at, backupCapability as b, ReadinessTimeoutError as bt, METHOD_ACCESS_MAP as c, validateExpressionSource as ct, ScopedTokenSchema as d, errMsg as dt, setByPath as et, StorageLocationTypeSchema as f, BaseAddon as ft, addonWidgetsCapability as g, DeviceFeature as gt, addonSettingsCapability as h, DEVICE_STATUS_METHOD as ht, BatteryStatusSchema as i, storageProviderCapability as it, enumerateItemArrayFields as j, nodePin as jt, doorbellCapability as k, hydrateSchema as kt, RUNTIME_DEFAULTS as l, vectorDimFromBase64 as lt, addonPagesCapability as m, DEVICE_SETTINGS_CONTRIBUTION_METHODS as mt, AlertSchema as n, snapshotCapability as nt, CoreBlockSchema as o, toExpressionValue as ot, UserRecordSchema as p, DATAPLANE_SECRET_HEADER as pt, metricsProviderCapability as q, ApiKeyRecordSchema as r, storageCapability as rt, DeviceStatusSchema as s, userManagementCapability as st, ALL_CAPABILITY_DEFINITIONS as t, settingsStoreCapability as tt, STREAM_PROFILE_META as u, vectorStoreCapability as ut, applyTransform as v, DeviceType as vt, dataStoreProviderCapability as w, asString as wt, buildStreamParamsConfigSchema as x, WELL_KNOWN_TAB_MAP as xt, authProviderCapability as y, ReadinessRegistry as yt, isObjectInput as z };
30424
+ export { setByPath as $, enumerateItemArrayFields as A, nodePin as At, kebabToCamel as B, dataStoreProviderCapability as C, asString as Ct, deviceStatusCapability as D, expandCapMethods as Dt, deviceStateCapability as E, emitReadiness as Et, getByPath as F, scopeKey as Ft, looseSchema as G, localNetworkCapability as H, isArrayOutputSchema as I, sleep as It, objectInputDeclaresAddonId as J, metricsProviderCapability as K, isCollectionArrayMethod as L, EventCategory as Lt, evaluateLinkExpression as M, parseJsonUnknown as Mt, extractNestedAddonId as N, readinessKey as Nt, doorbellCapability as O, hydrateSchema as Ot, filesystemBrowseCapability as P, resolveCapMount as Pt, scoreRuntimes as Q, isObjectInput as R, coreBlocksCapability as S, asNumber as St, deviceManagerCapability as T, emitDownForOwnedCaps as Tt, logDestinationCapability as U, lifecycleJobSchema as V, logLevelAtMost as W, platformProbeCapability as X, parseStreamParamsFormPatch as Y, procedureAuthKey as Z, alertsCapability as _, DeviceType as _t, CAP_NAMES_WITH_STATUS as a, toExpressionValue as at, backupCapability as b, WELL_KNOWN_TAB_MAP as bt, METHOD_ACCESS_MAP as c, vectorDimFromBase64 as ct, ScopedTokenSchema as d, BaseAddon as dt, settingsStoreCapability as et, StorageLocationTypeSchema as f, DATAPLANE_SECRET_HEADER as ft, addonWidgetsCapability as g, DeviceRole as gt, addonSettingsCapability as h, DeviceFeature as ht, BatteryStatusSchema as i, streamQualityLabel as it, enumerateSchemaFields as j, parseJsonObject as jt, enumerateInferenceDevices as k, isDeviceConfigCap as kt, RUNTIME_DEFAULTS as l, vectorStoreCapability as lt, addonPagesCapability as m, DEVICE_STATUS_METHOD as mt, AlertSchema as n, storageCapability as nt, CoreBlockSchema as o, userManagementCapability as ot, UserRecordSchema as p, DEVICE_SETTINGS_CONTRIBUTION_METHODS as pt, normalizeUnit as q, ApiKeyRecordSchema as r, storageProviderCapability as rt, DeviceStatusSchema as s, validateExpressionSource as st, ALL_CAPABILITY_DEFINITIONS as t, snapshotCapability as tt, STREAM_PROFILE_META as u, errMsg as ut, applyTransform as v, ReadinessRegistry as vt, decodeVectorBase64 as w, createEvent as wt, buildStreamParamsConfigSchema as x, asJsonObject as xt, authProviderCapability as y, ReadinessTimeoutError as yt, isVoidInput as z };
@@ -12845,7 +12845,22 @@ var RebuildObjectEmbeddingsInput = zod.z.object({
12845
12845
  * means the same thing.
12846
12846
  */
12847
12847
  var WipeObjectEmbeddingsResultSchema = zod.z.object({ deleted: zod.z.number() });
12848
+ /**
12849
+ * Acknowledgement that a rebuild STARTED.
12850
+ *
12851
+ * The pass costs ~1s per track — 45 minutes for a 2,600-track fleet — so it
12852
+ * runs detached and this returns immediately. Waiting for it made the client
12853
+ * time out while the work carried on server-side, which is the worst of both:
12854
+ * no result and no way to know it was still going. Poll
12855
+ * `getObjectEmbeddingRebuildStatus` for progress.
12856
+ */
12848
12857
  var RebuildObjectEmbeddingsResultSchema = zod.z.object({
12858
+ started: zod.z.boolean(),
12859
+ /** True when a pass was already running; the new request is ignored. */
12860
+ alreadyRunning: zod.z.boolean()
12861
+ });
12862
+ var RebuildStatusSchema = zod.z.object({
12863
+ running: zod.z.boolean(),
12849
12864
  scanned: zod.z.number(),
12850
12865
  rebuilt: zod.z.number(),
12851
12866
  /** Tracks whose key frame is gone — nothing to re-embed from. */
@@ -12853,8 +12868,12 @@ var RebuildObjectEmbeddingsResultSchema = zod.z.object({
12853
12868
  /** Tracks with no usable detection box. */
12854
12869
  missingBbox: zod.z.number(),
12855
12870
  failed: zod.z.number(),
12856
- /** False when the pass stopped at `maxTracks` with tracks left. */
12857
- complete: zod.z.boolean()
12871
+ /** Set once a pass ends: true only when EVERYTHING was covered. */
12872
+ complete: zod.z.boolean().nullable(),
12873
+ startedAtMs: zod.z.number().nullable(),
12874
+ finishedAtMs: zod.z.number().nullable(),
12875
+ /** Present when the pass ended by throwing. */
12876
+ error: zod.z.string().nullable()
12858
12877
  });
12859
12878
  var pipelineAnalyticsCapability = {
12860
12879
  name: "pipeline-analytics",
@@ -13129,15 +13148,15 @@ var pipelineAnalyticsCapability = {
13129
13148
  * `minScore`, sorted descending by score.
13130
13149
  */
13131
13150
  searchObjectEvents: method(SearchObjectEventsInput, zod.z.array(ScoredObjectEventSchema).readonly()),
13132
- wipeObjectEmbeddings: method(zod.z.void(), WipeObjectEmbeddingsResultSchema, {
13151
+ wipeObjectEmbeddings: method(zod.z.object({}), WipeObjectEmbeddingsResultSchema, {
13133
13152
  kind: "mutation",
13134
13153
  auth: "admin"
13135
13154
  }),
13136
13155
  rebuildObjectEmbeddings: method(RebuildObjectEmbeddingsInput, RebuildObjectEmbeddingsResultSchema, {
13137
13156
  kind: "mutation",
13138
- auth: "admin",
13139
- timeoutMs: 30 * 6e4
13140
- })
13157
+ auth: "admin"
13158
+ }),
13159
+ getObjectEmbeddingRebuildStatus: method(zod.z.object({}), RebuildStatusSchema)
13141
13160
  },
13142
13161
  events: {
13143
13162
  /**
@@ -27956,6 +27975,12 @@ var METHOD_ACCESS_MAP = Object.freeze({
27956
27975
  addonId: null,
27957
27976
  access: "view"
27958
27977
  },
27978
+ "pipelineAnalytics.getObjectEmbeddingRebuildStatus": {
27979
+ capName: "pipeline-analytics",
27980
+ capScope: "device",
27981
+ addonId: null,
27982
+ access: "view"
27983
+ },
27959
27984
  "pipelineAnalytics.getObjectEvents": {
27960
27985
  capName: "pipeline-analytics",
27961
27986
  capScope: "device",
@@ -30264,20 +30289,6 @@ TimelapseRuleInputSchema.extend({
30264
30289
  createdAt: zod.z.number(),
30265
30290
  updatedAt: zod.z.number()
30266
30291
  });
30267
- /** Cosine similarity between two embedding vectors */
30268
- function cosineSimilarity(a, b) {
30269
- if (a.length !== b.length) return 0;
30270
- let dotProduct = 0;
30271
- let normA = 0;
30272
- let normB = 0;
30273
- for (let i = 0; i < a.length; i++) {
30274
- dotProduct += a[i] * b[i];
30275
- normA += a[i] * a[i];
30276
- normB += b[i] * b[i];
30277
- }
30278
- const denom = Math.sqrt(normA) * Math.sqrt(normB);
30279
- return denom === 0 ? 0 : dotProduct / denom;
30280
- }
30281
30292
  /**
30282
30293
  * Decode base64 little-endian Float32 back into a vector.
30283
30294
  *
@@ -30626,12 +30637,6 @@ Object.defineProperty(exports, "coreBlocksCapability", {
30626
30637
  return coreBlocksCapability;
30627
30638
  }
30628
30639
  });
30629
- Object.defineProperty(exports, "cosineSimilarity", {
30630
- enumerable: true,
30631
- get: function() {
30632
- return cosineSimilarity;
30633
- }
30634
- });
30635
30640
  Object.defineProperty(exports, "createEvent", {
30636
30641
  enumerable: true,
30637
30642
  get: function() {
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_chunk = require("./chunk-Cek0wNdY.js");
3
- const require_dist = require("./dist-DHU3Uq9p.js");
3
+ const require_dist = require("./dist-CblJsHb-.js");
4
4
  const require_model_download_service = require("./model-download-service-hf0ookyy.js");
5
5
  const require_manifest_python_deps = require("./manifest-python-deps-BqE5j0-O.js");
6
6
  const require_resource_monitor = require("./resource-monitor-DNNomR-i.js");
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as __toCommonJS, i as __require, n as __esmMin, o as __toESM$1, r as __exportAll, t as __commonJSMin$1 } from "./chunk-CNf5ZN-e.mjs";
2
- import { B as isVoidInput, Ct as asNumber, Et as emitDownForOwnedCaps, Ft as resolveCapMount, G as logLevelAtMost, H as lifecycleJobSchema, It as scopeKey, K as looseSchema, L as isArrayOutputSchema, Mt as parseJsonObject, Nt as parseJsonUnknown$1, Ot as expandCapMethods, P as extractNestedAddonId, Pt as readinessKey, Q as procedureAuthKey, R as isCollectionArrayMethod, Rt as EventCategory$1, St as asJsonObject$1, Tt as createEvent, V as kebabToCamel, Y as objectInputDeclaresAddonId, bt as ReadinessTimeoutError, c as METHOD_ACCESS_MAP, dt as errMsg$1, h as addonSettingsCapability, ht as DEVICE_STATUS_METHOD, l as RUNTIME_DEFAULTS, mt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, pt as DATAPLANE_SECRET_HEADER$1, t as ALL_CAPABILITY_DEFINITIONS, wt as asString$1, yt as ReadinessRegistry, z as isObjectInput } from "./dist-C-I9UG-Y.mjs";
2
+ import { B as kebabToCamel, Ct as asString$1, Dt as expandCapMethods, Ft as scopeKey, G as looseSchema, I as isArrayOutputSchema, J as objectInputDeclaresAddonId, L as isCollectionArrayMethod, Lt as EventCategory$1, Mt as parseJsonUnknown$1, N as extractNestedAddonId, Nt as readinessKey, Pt as resolveCapMount, R as isObjectInput, St as asNumber, Tt as emitDownForOwnedCaps, V as lifecycleJobSchema, W as logLevelAtMost, Z as procedureAuthKey, c as METHOD_ACCESS_MAP, ft as DATAPLANE_SECRET_HEADER$1, h as addonSettingsCapability, jt as parseJsonObject, l as RUNTIME_DEFAULTS, mt as DEVICE_STATUS_METHOD, pt as DEVICE_SETTINGS_CONTRIBUTION_METHODS, t as ALL_CAPABILITY_DEFINITIONS, ut as errMsg$1, vt as ReadinessRegistry, wt as createEvent, xt as asJsonObject$1, yt as ReadinessTimeoutError, z as isVoidInput } from "./dist-BOpRqInW.mjs";
3
3
  import { a as downloadModel, c as getModelFilePath, d as contentTypeFor, f as createAuthenticatedFileServer, h as resolveFilePath, i as downloadFile, l as isModelDownloaded, m as parseTokenizedUrl, n as collectModelFiles, o as ensureModel, p as parseRangeHeader, r as deleteModelFromDisk, s as fetchJson, t as ModelDownloadService, u as createFileDataPlaneHandler } from "./model-download-service-Cp9f4dk6.mjs";
4
4
  import { $ as buildNativeCapProxy, A as createHubCapForwardService, B as AGENT_CAP_FWD_ACTION, C as brokerTransportLink, Ct as resolveAddonClass, D as localProviderLink, E as ipcParentLink, F as createUdsLogger, G as callWithServiceDiscovery, H as CapRouteResolver, I as createUdsLoggerWithControl, J as UdsLocalTransportServer, K as createLocalTransport, L as LocalChildClient, M as createUdsEventBridge, N as createUdsEventBus, O as HUB_CAP_FWD_ACTION, P as udsChildLogToWorkerEntry, Q as encodeFrame, R as LocalChildRegistry, S as brokerCallForCap, St as runNpm, T as ipcChildLink, U as CapRouteError, V as AGENT_CAP_FWD_SERVICE, W as classifyCapRoute, X as localEndpointPath, Y as SocketChannel, Z as FrameDecoder, _ as createKernelHwAccel, _t as CapabilityHandle, a as getWorkerDeviceRegistry, b as __resetCapUsageRegistryForTests, bt as installManifestNativeDeps, c as setHubConnected, ct as NATIVE_PROVIDER_SERVICE_INFIX, d as getBrokerEventBus, dt as capBareAction, et as buildUdsNativeCapProxy, f as getMoleculerEventStats, ft as capServiceName, g as AddonDepsManager, gt as DeviceRegistry, h as subscribePassthrough, ht as serializeTypedArrays, i as createUdsAddonContext, it as mountNativeCapService, j as createParentUnownedCallHandler, k as HUB_CAP_FWD_SERVICE, l as EVENT_TOPIC_PREFIX, lt as capActionName, m as setNodeEventInterest, mt as deserializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as createAddonService, p as registerEventBusService, pt as parseCapAction, q as UdsLocalTransportClient, r as createAddonContext, s as getOrInitReadinessRegistryForClient, st as validateProviderRegistrations, t as installManifestPythonDeps, tt as createBrokerDeviceManagerApi, u as clusterEventTopic, ut as capActionSuffix, v as resolveHwAccel, vt as CapabilityUnavailableError, w as buildLinkChain, wt as createAddonDataPlaneFacility, x as getCapUsageRegistry, xt as resolveNpmInvocation, y as CapUsageRegistry, yt as copyBundledNativeModules, z as UDS_NO_ROUTE_PREFIX } from "./manifest-python-deps-Ck4-9K9m.mjs";
5
5
  import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-BkP504Vq.mjs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/system",
3
- "version": "1.2.52",
3
+ "version": "1.2.54",
4
4
  "description": "Core addon for CamStack — builtins, pipeline, process management, auth, logging, events",
5
5
  "keywords": [
6
6
  "camstack",
@@ -337,9 +337,9 @@
337
337
  "publish": "npm publish --access public"
338
338
  },
339
339
  "dependencies": {
340
- "@camstack/types": "*",
341
340
  "@camstack/sdk": "*",
342
341
  "@camstack/shm-ring": "*",
342
+ "@camstack/types": "*",
343
343
  "@msgpack/msgpack": "^3.1.3",
344
344
  "@trpc/client": "^11.16.0",
345
345
  "@trpc/server": "^11.16.0",
@@ -350,6 +350,7 @@
350
350
  "jsonwebtoken": "^9.0.0",
351
351
  "moleculer": "^0.15.0",
352
352
  "otplib": "13.4.1",
353
+ "sqlite-vec": "^0.1.9",
353
354
  "superjson": "^2.2.0",
354
355
  "systeminformation": "^5.0.0",
355
356
  "tar": "7.5.16",
@@ -1,197 +0,0 @@
1
- import { IScopedLogger, VectorFilter, VectorItem, VectorMatch, VectorMetadata, VectorMetric } from '@camstack/types';
2
- /** Metadata keys promoted to real, indexable columns. */
3
- export declare const PROMOTED_COLUMNS: readonly ["deviceId", "timestamp", "className", "modelId"];
4
- /** Ceiling on rows compared in one query, so a pathological index cannot wedge the runner. */
5
- export declare const MAX_SCAN_ROWS = 200000;
6
- /** Per-index declaration kept in memory; re-declared on boot by each caller. */
7
- export interface VectorIndexSpec {
8
- readonly dim: number;
9
- readonly metric: VectorMetric;
10
- }
11
- /**
12
- * The slice of `SqliteSettingsBackend` this index uses.
13
- *
14
- * Narrowed on purpose: the real backend satisfies it structurally and a test
15
- * fake implements exactly these four methods without a cast. Depending on the
16
- * whole backend would have forced an `as any` in the fake, which is how a fake
17
- * ends up quietly diverging from the surface it stands in for.
18
- */
19
- export interface VectorBackend {
20
- declareCollection(input: {
21
- collection: string;
22
- columns: readonly TableColumn[];
23
- indexes?: readonly TableIndex[];
24
- }): Promise<void>;
25
- set(input: {
26
- collection: string;
27
- key: string;
28
- value: unknown;
29
- }): Promise<void>;
30
- delete(input: {
31
- collection: string;
32
- key: string;
33
- }): Promise<void>;
34
- query(input: {
35
- collection: string;
36
- filter?: StoreQueryFilter;
37
- }): Promise<readonly StoreRecord[]>;
38
- /**
39
- * Bulk delete in ONE statement.
40
- *
41
- * `deleteByFilter` used to collect ids and delete them one at a time, which
42
- * on a live index of 8,686 rows blew through a 60s UDS timeout mid-way and
43
- * left the index half-emptied. The engine has always had this; using it is
44
- * the difference between one statement and eight thousand.
45
- */
46
- deleteWhere(input: {
47
- collection: string;
48
- filter: StoreQueryFilter;
49
- }): Promise<{
50
- deleted: number;
51
- }>;
52
- }
53
- /** Column spec accepted by `declareCollection`. */
54
- export interface TableColumn {
55
- readonly name: string;
56
- readonly type: 'TEXT' | 'INTEGER' | 'REAL' | 'JSON' | 'BOOLEAN';
57
- readonly primaryKey?: boolean;
58
- readonly notNull?: boolean;
59
- }
60
- /** Index spec accepted by `declareCollection`. */
61
- export interface TableIndex {
62
- readonly name: string;
63
- readonly columns: readonly string[];
64
- }
65
- /** The filter shape this index sends to the store. */
66
- export interface StoreQueryFilter {
67
- readonly where?: Record<string, unknown>;
68
- readonly whereBetween?: Record<string, [number, number]>;
69
- readonly orderBy?: {
70
- field: string;
71
- direction: 'asc' | 'desc';
72
- };
73
- readonly limit?: number;
74
- }
75
- /** A row as the store returns it. */
76
- export interface StoreRecord {
77
- readonly id: string;
78
- readonly data: Record<string, unknown>;
79
- }
80
- export interface SqliteVectorIndexDeps {
81
- readonly store: VectorBackend;
82
- readonly logger: IScopedLogger;
83
- }
84
- interface StoredRow {
85
- readonly vector: string;
86
- readonly deviceId: number | null;
87
- readonly timestamp: number | null;
88
- readonly className: string | null;
89
- readonly modelId: string | null;
90
- readonly extra: VectorMetadata;
91
- }
92
- export declare class SqliteVectorIndex {
93
- private readonly store;
94
- private readonly logger;
95
- private readonly specs;
96
- constructor(deps: SqliteVectorIndexDeps);
97
- /**
98
- * Load persisted index declarations. Call once at startup, BEFORE serving:
99
- * without it every method on an existing index throws until a write
100
- * re-declares it.
101
- */
102
- loadIndexRegistry(): Promise<void>;
103
- /**
104
- * Idempotent. Re-declaring an index with a DIFFERENT dim throws rather than
105
- * wiping: silently dropping a populated index because a caller shipped a new
106
- * model would destroy history that cannot be rebuilt.
107
- */
108
- declareIndex(index: string, dim: number, metric: VectorMetric): Promise<void>;
109
- /**
110
- * Resolve an index's spec, recovering it from stored rows when the registry
111
- * has no entry.
112
- *
113
- * The recovery is not belt-and-braces, it is required: indexes created before
114
- * the registry existed have rows and no declaration, and so would be
115
- * permanently unqueryable — which is exactly how this was found, with 8,494
116
- * live vectors that `stats` refused to look at. The dimension is derivable
117
- * from any stored vector, so derive it and persist it rather than demanding
118
- * the caller redeclare. The metric is NOT derivable and falls back to
119
- * `cosine`, which is what every current caller declares.
120
- */
121
- private resolveSpec;
122
- /** Upsert items, refusing any whose vector length disagrees with the index. */
123
- upsert(index: string, items: readonly VectorItem[]): Promise<{
124
- upserted: number;
125
- rejected: number;
126
- }>;
127
- /** Exhaustive ranked search over the rows a prefilter admits. */
128
- query(params: {
129
- index: string;
130
- vector: string;
131
- topK: number;
132
- minScore?: number;
133
- filter?: VectorFilter;
134
- }): Promise<{
135
- matches: VectorMatch[];
136
- scanned: number;
137
- truncated: boolean;
138
- }>;
139
- /**
140
- * Metadata for the given ids, WITHOUT decoding their vectors.
141
- *
142
- * The caller is a best-of gate comparing confidences, so the vector is dead
143
- * weight on that path — reading it would reintroduce exactly the per-row cost
144
- * this index exists to remove. Missing ids are absent from the result rather
145
- * than present with an empty metadata object.
146
- */
147
- getByIds(index: string, ids: readonly string[]): Promise<Array<{
148
- id: string;
149
- metadata: VectorMetadata;
150
- }>>;
151
- deleteByIds(index: string, ids: readonly string[]): Promise<number>;
152
- /**
153
- * Delete every row the filter admits.
154
- *
155
- * When every clause is pushable, this is ONE bulk statement. When the filter
156
- * touches a non-promoted key it falls back to select-then-delete, because
157
- * those clauses live in the JSON remainder and only JS can evaluate them —
158
- * and an unapplied clause would delete rows the caller wanted kept, which is
159
- * the one failure mode a delete must not have.
160
- */
161
- deleteByFilter(index: string, filter: VectorFilter): Promise<number>;
162
- stats(index: string): Promise<{
163
- backend: string;
164
- count: number;
165
- dim: number;
166
- metric: VectorMetric;
167
- exact: boolean;
168
- }>;
169
- }
170
- /** Split caller metadata into promoted columns plus a verbatim remainder. */
171
- export declare function splitMetadata(metadata: VectorMetadata): {
172
- deviceId: number | null;
173
- timestamp: number | null;
174
- className: string | null;
175
- modelId: string | null;
176
- extra: VectorMetadata;
177
- };
178
- /** Rebuild the caller's metadata from the promoted columns plus the remainder. */
179
- export declare function rebuildMetadata(row: StoredRow): VectorMetadata;
180
- /** The part of a filter SQLite can apply: promoted columns only. */
181
- export declare function buildSqlFilter(filter: VectorFilter | undefined): {
182
- where?: Record<string, unknown>;
183
- whereBetween?: Record<string, [number, number]>;
184
- };
185
- /**
186
- * Apply the clauses SQL could not.
187
- *
188
- * A filter key that is not a promoted column lives inside the `extra` JSON
189
- * blob, so it is checked here in JS. It is applied rather than ignored — an
190
- * unapplied filter returns rows the caller will treat as matches.
191
- */
192
- export declare function passesUnpushedFilter(row: StoredRow, filter: VectorFilter | undefined): boolean;
193
- /** True when every clause of the filter maps to a promoted column. */
194
- export declare function isFullyPushable(filter: VectorFilter): boolean;
195
- /** Score two vectors under the index's metric. Higher is nearer in every case. */
196
- export declare function scoreFor(metric: VectorMetric, a: Float32Array, b: Float32Array): number;
197
- export {};