@camstack/system 1.2.456 → 1.2.458

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 (123) hide show
  1. package/dist/addon-runner.js +259 -37
  2. package/dist/addon-runner.mjs +289 -67
  3. package/dist/{agent-https-fm4AR8XL.mjs → agent-https-CQA3W-3e.mjs} +2 -2
  4. package/dist/{agent-https-yjxdfJDA.js → agent-https-DOELEug8.js} +2 -2
  5. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  6. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +1 -1
  7. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  8. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +1 -1
  9. package/dist/builtins/alerts/alerts.addon.js +2 -2
  10. package/dist/builtins/alerts/alerts.addon.mjs +2 -2
  11. package/dist/builtins/autotrack/index.js +1 -1
  12. package/dist/builtins/autotrack/index.mjs +1 -1
  13. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  14. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2 -2
  15. package/dist/builtins/calendars/calendars.addon.js +1 -1
  16. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  17. package/dist/builtins/camera-grid/index.js +1 -1
  18. package/dist/builtins/camera-grid/index.mjs +1 -1
  19. package/dist/builtins/composer/composer.addon.js +2 -2
  20. package/dist/builtins/composer/composer.addon.mjs +2 -2
  21. package/dist/builtins/console-logging/console-destination.d.ts +1 -2
  22. package/dist/builtins/console-logging/index.js +1 -4
  23. package/dist/builtins/console-logging/index.mjs +1 -4
  24. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  25. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  26. package/dist/builtins/device-history/capture/capture-engine.d.ts +6 -0
  27. package/dist/builtins/device-history/device-history.addon.d.ts +13 -0
  28. package/dist/builtins/device-history/device-history.addon.js +736 -315
  29. package/dist/builtins/device-history/device-history.addon.mjs +736 -315
  30. package/dist/builtins/device-history/ingest/producer-ingest.d.ts +11 -1
  31. package/dist/builtins/device-history/query/history-query.d.ts +35 -9
  32. package/dist/builtins/device-history/query/point-shape.d.ts +33 -0
  33. package/dist/builtins/device-history/retention/retention.d.ts +1 -1
  34. package/dist/builtins/device-history/rollup/rollup-engine.d.ts +2 -0
  35. package/dist/builtins/device-history/rollup/rollup-math.d.ts +6 -0
  36. package/dist/builtins/device-history/store/history-store.d.ts +7 -0
  37. package/dist/builtins/device-history/store/series-registry.d.ts +26 -1
  38. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  39. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  40. package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts +1 -2
  41. package/dist/builtins/hub-forwarder/index.js +1 -4
  42. package/dist/builtins/hub-forwarder/index.mjs +1 -4
  43. package/dist/builtins/keychain/index.js +4 -4
  44. package/dist/builtins/keychain/index.mjs +4 -4
  45. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +1 -1
  46. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +1 -1
  47. package/dist/builtins/local-auth/local-auth.addon.js +3 -3
  48. package/dist/builtins/local-auth/local-auth.addon.mjs +3 -3
  49. package/dist/builtins/local-network/local-network.addon.js +2 -2
  50. package/dist/builtins/local-network/local-network.addon.mjs +2 -2
  51. package/dist/builtins/loki-logging/index.js +323 -7
  52. package/dist/builtins/loki-logging/index.mjs +323 -7
  53. package/dist/builtins/loki-logging/loki-destination.d.ts +20 -3
  54. package/dist/builtins/loki-logging/loki-read.d.ts +51 -0
  55. package/dist/builtins/native-metrics/native-metrics.addon.js +290 -112
  56. package/dist/builtins/native-metrics/native-metrics.addon.mjs +290 -112
  57. package/dist/builtins/native-metrics/node-metrics-history-recorder.d.ts +106 -35
  58. package/dist/builtins/platform-probe/coral-accelerators.d.ts +26 -9
  59. package/dist/builtins/platform-probe/index.js +11 -68
  60. package/dist/builtins/platform-probe/index.mjs +11 -68
  61. package/dist/builtins/record-entries/index.js +1 -1
  62. package/dist/builtins/record-entries/index.mjs +1 -1
  63. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  64. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  65. package/dist/builtins/snapshot/index.js +1 -1
  66. package/dist/builtins/snapshot/index.mjs +1 -1
  67. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  68. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +1 -1
  69. package/dist/builtins/sqlite-storage/index.js +1 -1
  70. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  71. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +2 -2
  72. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +2 -2
  73. package/dist/builtins/storage-orchestrator/location-history-recorder.d.ts +76 -0
  74. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +9 -0
  75. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +144 -1
  76. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +144 -1
  77. package/dist/builtins/system-config/system-config.addon.js +3 -3
  78. package/dist/builtins/system-config/system-config.addon.mjs +3 -3
  79. package/dist/builtins/winston-logging/index.js +165 -3
  80. package/dist/builtins/winston-logging/index.mjs +165 -3
  81. package/dist/builtins/winston-logging/log-file-cursor.d.ts +12 -0
  82. package/dist/builtins/winston-logging/log-file-index-store.d.ts +11 -0
  83. package/dist/builtins/winston-logging/log-file-index.d.ts +77 -0
  84. package/dist/builtins/winston-logging/log-file-read-client.d.ts +44 -0
  85. package/dist/builtins/winston-logging/log-file-read-protocol.d.ts +41 -0
  86. package/dist/builtins/winston-logging/log-file-read-worker.d.ts +1 -0
  87. package/dist/builtins/winston-logging/log-file-reader.d.ts +51 -0
  88. package/dist/builtins/winston-logging/winston-destination.d.ts +20 -2
  89. package/dist/{composition-sources-Ds0Vr6eD.mjs → composition-sources-BVguN7VV.mjs} +1 -1
  90. package/dist/{composition-sources-gB4coDJR.js → composition-sources-DURQNDJ4.js} +1 -1
  91. package/dist/{constants-i5oD_gLB.mjs → constants-FGjnsE2x.mjs} +1 -1
  92. package/dist/{constants-CavyKfHZ.js → constants-Njka8Cv6.js} +1 -1
  93. package/dist/coral-accelerators-Bi_c3Rft.js +175 -0
  94. package/dist/coral-accelerators-DcnZvctM.mjs +162 -0
  95. package/dist/{device-ca-bpoEr0zG.js → device-ca-BrVK_5s3.js} +1 -1
  96. package/dist/{device-ca-qz1Pmeu1.mjs → device-ca-lEaAQ9Xi.mjs} +1 -1
  97. package/dist/{dist-BpqA2CT0.js → dist-BZQjLPiz.js} +526 -57
  98. package/dist/{dist-BSF_C8W2.mjs → dist-B_GRPhnY.mjs} +509 -58
  99. package/dist/file-host-worker.js +1 -1
  100. package/dist/file-host-worker.mjs +1 -1
  101. package/dist/{hub-mdns-ciao-CHaGDzyz.mjs → hub-mdns-ciao-Bg2HfTwP.mjs} +2 -2
  102. package/dist/{hub-mdns-ciao-CZlZRxxA.js → hub-mdns-ciao-nce3TXs_.js} +2 -2
  103. package/dist/index.d.ts +1 -0
  104. package/dist/index.js +140 -48
  105. package/dist/index.mjs +134 -49
  106. package/dist/kernel/config-schema.d.ts +5 -0
  107. package/dist/kernel/hwaccel/hwaccel-resolver.d.ts +7 -3
  108. package/dist/kernel/moleculer/accessory-prune-gate.d.ts +55 -0
  109. package/dist/log-file-read-protocol-B7M3X3bT.mjs +785 -0
  110. package/dist/log-file-read-protocol-D0WcLbIV.js +817 -0
  111. package/dist/log-file-read-worker.js +64 -0
  112. package/dist/log-file-read-worker.mjs +64 -0
  113. package/dist/log-read-filter-Bi066jwU.js +134 -0
  114. package/dist/log-read-filter-D7Ev3zm-.mjs +93 -0
  115. package/dist/logging/log-manager.d.ts +10 -6
  116. package/dist/logging/log-read-filter.d.ts +43 -0
  117. package/dist/{phase6-declare-gate-n-IZRklX.js → phase6-declare-gate-Dag1_WR2.js} +1 -1
  118. package/dist/{phase6-declare-gate-B4yfsf2n.mjs → phase6-declare-gate-Lb-mrVvz.mjs} +1 -1
  119. package/dist/{restore-archive-BGUM4FKf.mjs → restore-archive-C7kLDI_0.mjs} +1 -1
  120. package/dist/{restore-archive-B4QG7XmX.js → restore-archive-FyfZ8YMC.js} +1 -1
  121. package/dist/{wal-maintenance-CNEs_I94.js → wal-maintenance-DfSIOj24.js} +0 -0
  122. package/dist/{wal-maintenance-AerF4XE6.mjs → wal-maintenance-Duejh7Lx.mjs} +0 -0
  123. package/package.json +1 -1
@@ -5467,6 +5467,67 @@ function createChildrenBatchLoader(opts) {
5467
5467
  } };
5468
5468
  }
5469
5469
  //#endregion
5470
+ //#region src/kernel/moleculer/accessory-prune-gate.ts
5471
+ function isSpecList(answer) {
5472
+ return Array.isArray(answer);
5473
+ }
5474
+ function classifyAccessoryRead(answer, ctx) {
5475
+ if (isSpecList(answer)) {
5476
+ if (!ctx.online) return {
5477
+ kind: "unknown",
5478
+ reason: "parent offline",
5479
+ children: answer
5480
+ };
5481
+ if (ctx.probedAt === 0) return {
5482
+ kind: "unknown",
5483
+ reason: "probe not yet completed",
5484
+ children: answer
5485
+ };
5486
+ return {
5487
+ kind: "successful",
5488
+ children: answer
5489
+ };
5490
+ }
5491
+ if (answer.kind === "unknown") return {
5492
+ kind: "unknown",
5493
+ reason: answer.reason,
5494
+ children: answer.known ?? []
5495
+ };
5496
+ return {
5497
+ kind: "successful",
5498
+ children: answer.children
5499
+ };
5500
+ }
5501
+ /** One per parent registration; in-memory on purpose (a restart starts over — the safe direction). */
5502
+ var AccessoryShrinkGate = class {
5503
+ /** childId → the probe (`lastProbedAt`) of the first successful read that lacked it. */
5504
+ #firstMissing = /* @__PURE__ */ new Map();
5505
+ /**
5506
+ * `missing` = the managed children a SUCCESSFUL read no longer lists. Never
5507
+ * call this for an unknown read.
5508
+ */
5509
+ decide(missing, probedAt) {
5510
+ const missingSet = new Set(missing);
5511
+ for (const id of [...this.#firstMissing.keys()]) if (!missingSet.has(id)) this.#firstMissing.delete(id);
5512
+ const prune = [];
5513
+ const deferred = [];
5514
+ for (const id of missing) {
5515
+ const first = this.#firstMissing.get(id);
5516
+ if (first !== void 0 && probedAt > first) {
5517
+ prune.push(id);
5518
+ this.#firstMissing.delete(id);
5519
+ continue;
5520
+ }
5521
+ if (first === void 0) this.#firstMissing.set(id, probedAt);
5522
+ deferred.push(id);
5523
+ }
5524
+ return {
5525
+ prune,
5526
+ deferred
5527
+ };
5528
+ }
5529
+ };
5530
+ //#endregion
5470
5531
  //#region src/kernel/moleculer/runtime-state-load.ts
5471
5532
  /** A device build refused because its runtime state could not be loaded. */
5472
5533
  var RuntimeStateLoadError = class extends Error {
@@ -6200,6 +6261,7 @@ function createBrokerDeviceManagerApi(opts) {
6200
6261
  throw err;
6201
6262
  }
6202
6263
  const lifecycleHost = device;
6264
+ const shrinkGate = new AccessoryShrinkGate();
6203
6265
  const runReconcile = async () => {
6204
6266
  try {
6205
6267
  await callDeviceManager(api, "registerDevice", {
@@ -6223,7 +6285,12 @@ function createBrokerDeviceManagerApi(opts) {
6223
6285
  });
6224
6286
  }
6225
6287
  if (typeof lifecycleHost.getAccessoryChildren !== "function") return;
6226
- const specs = lifecycleHost.getAccessoryChildren();
6288
+ const probedAt = device.runtimeState?.getCapState("feature-probe")?.lastProbedAt ?? 0;
6289
+ const read = classifyAccessoryRead(lifecycleHost.getAccessoryChildren(), {
6290
+ online: device.online,
6291
+ probedAt
6292
+ });
6293
+ const specs = read.children;
6227
6294
  const expected = new Set(specs.map((s) => `${device.stableId}-${s.stableIdSuffix}`));
6228
6295
  await runBounded(specs, ACCESSORY_SPAWN_CONCURRENCY, async (spec) => {
6229
6296
  try {
@@ -6241,24 +6308,42 @@ function createBrokerDeviceManagerApi(opts) {
6241
6308
  });
6242
6309
  }
6243
6310
  });
6244
- if ((device.runtimeState?.getCapState("feature-probe")?.lastProbedAt ?? 0) === 0 && specs.length === 0) {
6245
- opts.logger.debug("Accessory orphan reconciliation skipped — probe not yet completed", { tags: {
6246
- parentDeviceId: device.id,
6247
- parentStableId: device.stableId
6248
- } });
6311
+ if (read.kind === "unknown") {
6312
+ opts.logger.info("Accessory orphan reconciliation skipped — child list unknown", {
6313
+ tags: {
6314
+ deviceId: device.id,
6315
+ parentStableId: device.stableId
6316
+ },
6317
+ meta: {
6318
+ reason: read.reason,
6319
+ probedAt
6320
+ }
6321
+ });
6249
6322
  return;
6250
6323
  }
6251
6324
  try {
6252
- const currentChildren = await childrenLoader.load(device.id);
6253
- for (const child of currentChildren) {
6254
- if (child.linkDeviceId !== device.id) continue;
6255
- if (expected.has(child.stableId)) continue;
6325
+ const missing = (await childrenLoader.load(device.id)).filter((child) => child.linkDeviceId === device.id && !expected.has(child.stableId));
6326
+ const decision = shrinkGate.decide(missing.map((child) => child.id), probedAt);
6327
+ if (decision.deferred.length > 0) opts.logger.info("Accessory children missing from a complete read — kept until a later probe agrees", {
6328
+ tags: {
6329
+ deviceId: device.id,
6330
+ parentStableId: device.stableId
6331
+ },
6332
+ meta: {
6333
+ childDeviceIds: [...decision.deferred],
6334
+ probedAt
6335
+ }
6336
+ });
6337
+ const confirmed = new Set(decision.prune);
6338
+ for (const child of missing) {
6339
+ if (!confirmed.has(child.id)) continue;
6256
6340
  const live = registry.getById(child.id);
6257
6341
  try {
6258
6342
  if (live) await deviceApi.remove(child.id);
6259
6343
  else await callDeviceManager(api, "removeDevice", { deviceId: child.id });
6260
6344
  opts.logger.info("Removed orphan accessory child no longer in parent specs", {
6261
6345
  tags: {
6346
+ deviceId: child.id,
6262
6347
  parentDeviceId: device.id,
6263
6348
  parentStableId: device.stableId
6264
6349
  },
@@ -6271,6 +6356,7 @@ function createBrokerDeviceManagerApi(opts) {
6271
6356
  } catch (err) {
6272
6357
  opts.logger.warn("Failed to remove orphan accessory child", {
6273
6358
  tags: {
6359
+ deviceId: child.id,
6274
6360
  parentDeviceId: device.id,
6275
6361
  parentStableId: device.stableId,
6276
6362
  childDeviceId: child.id
@@ -7779,6 +7865,166 @@ function ipcParentLink(getCallOut) {
7779
7865
  };
7780
7866
  }
7781
7867
  //#endregion
7868
+ //#region src/builtins/platform-probe/coral-accelerators.ts
7869
+ /**
7870
+ * Coral USB Edge TPU USB identifiers.
7871
+ *
7872
+ * The device enumerates as `1a6e:089a` (Global Unichip) BEFORE the libedgetpu
7873
+ * firmware loads, then re-enumerates as `18d1:9302` (Google) AFTER. Either id
7874
+ * means a Coral is physically attached, so both count as a positive signal.
7875
+ */
7876
+ var CORAL_USB_IDS = [{
7877
+ vendor: "1a6e",
7878
+ product: "089a"
7879
+ }, {
7880
+ vendor: "18d1",
7881
+ product: "9302"
7882
+ }];
7883
+ /** The PCIe / M.2 Coral's PCI function id (Global Unichip "Apex"). */
7884
+ var CORAL_PCI_VENDOR = "0x1ac1";
7885
+ var CORAL_PCI_DEVICE = "0x089a";
7886
+ /** A unit the apex driver bound: `/sys/class/apex/apex_<N>` ↔ `/dev/apex_<N>`. */
7887
+ var APEX_ENTRY = /^apex_(\d+)$/;
7888
+ /**
7889
+ * Default install path of the libedgetpu delegate on the hub, provisioned
7890
+ * out-of-band by `/data/deps/edgetpu-install.sh` (it is a system shared
7891
+ * library, not a pip package). Overridable via `CAMSTACK_EDGETPU_LIB` — kept in
7892
+ * sync with the Python pool's own default in `inference_pool.py`.
7893
+ */
7894
+ var DEFAULT_EDGETPU_LIB = "/data/deps/edgetpu/lib/libedgetpu.so.1";
7895
+ function countUsbCorals(fsx) {
7896
+ let count = 0;
7897
+ for (const device of fsx.listUsbDevices()) {
7898
+ const vendor = fsx.readUsbAttr(device, "idVendor").toLowerCase();
7899
+ const product = fsx.readUsbAttr(device, "idProduct").toLowerCase();
7900
+ if (CORAL_USB_IDS.some((id) => id.vendor === vendor && id.product === product)) count++;
7901
+ }
7902
+ return count;
7903
+ }
7904
+ function countPciCorals(fsx) {
7905
+ let count = 0;
7906
+ for (const device of fsx.listPciDevices()) {
7907
+ const vendor = fsx.readPciAttr(device, "vendor").toLowerCase();
7908
+ const product = fsx.readPciAttr(device, "device").toLowerCase();
7909
+ if (vendor === CORAL_PCI_VENDOR && product === CORAL_PCI_DEVICE) count++;
7910
+ }
7911
+ return count;
7912
+ }
7913
+ /**
7914
+ * PCIe units: each `/sys/class/apex/apex_N` is a unit the driver bound; it is
7915
+ * usable only when `/dev/apex_N` is in this process's view AND opens read/write.
7916
+ * PCI functions with the Coral id beyond the bound units have no driver.
7917
+ */
7918
+ function classifyPci(fsx) {
7919
+ let usable = 0;
7920
+ let notAccessible = 0;
7921
+ for (const entry of fsx.listApexClass()) {
7922
+ const match = APEX_ENTRY.exec(entry);
7923
+ if (match === null) continue;
7924
+ const node = `/dev/apex_${match[1]}`;
7925
+ if (fsx.exists(node) && fsx.canOpen(node)) usable++;
7926
+ else notAccessible++;
7927
+ }
7928
+ const driverMissing = Math.max(0, countPciCorals(fsx) - usable - notAccessible);
7929
+ return {
7930
+ usable,
7931
+ notAccessible,
7932
+ driverMissing
7933
+ };
7934
+ }
7935
+ /**
7936
+ * Detect Coral Edge TPUs on USB and PCIe/M.2.
7937
+ *
7938
+ * - USB: every matching USB device counts (multiple Corals run concurrently).
7939
+ * - PCIe: the apex driver's units, each usable only if its device node opens;
7940
+ * a Coral PCI function the driver did not bind is `driver-missing`.
7941
+ * - Fallback: when NO Coral signal of either bus is visible but the libedgetpu
7942
+ * delegate is installed (a container whose `/sys` USB view is limited), one
7943
+ * USB Coral is assumed — never when a PCI Coral was seen, since the delegate
7944
+ * then says nothing about USB.
7945
+ *
7946
+ * Returns `null` only when no Coral was found at all; a present-but-unusable
7947
+ * Coral is reported with its typed reason, never as absent (D393/D315).
7948
+ */
7949
+ function classifyCoralAccelerator(fsx) {
7950
+ const usb = countUsbCorals(fsx);
7951
+ const pci = classifyPci(fsx);
7952
+ const units = [];
7953
+ if (usb > 0) units.push({
7954
+ bus: "usb",
7955
+ count: usb
7956
+ });
7957
+ if (pci.usable > 0) units.push({
7958
+ bus: "pci",
7959
+ count: pci.usable
7960
+ });
7961
+ const unavailable = [];
7962
+ if (pci.driverMissing > 0) unavailable.push({
7963
+ bus: "pci",
7964
+ count: pci.driverMissing,
7965
+ reason: "driver-missing"
7966
+ });
7967
+ if (pci.notAccessible > 0) unavailable.push({
7968
+ bus: "pci",
7969
+ count: pci.notAccessible,
7970
+ reason: "device-not-accessible"
7971
+ });
7972
+ if (units.length > 0 || unavailable.length > 0) return unavailable.length > 0 ? {
7973
+ type: "coral-edgetpu",
7974
+ units,
7975
+ unavailable
7976
+ } : {
7977
+ type: "coral-edgetpu",
7978
+ units
7979
+ };
7980
+ const libPath = process.env["CAMSTACK_EDGETPU_LIB"] ?? DEFAULT_EDGETPU_LIB;
7981
+ if (fsx.exists(libPath)) return {
7982
+ type: "coral-edgetpu",
7983
+ units: [{
7984
+ bus: "usb",
7985
+ count: 1
7986
+ }]
7987
+ };
7988
+ return null;
7989
+ }
7990
+ function safeList(dir) {
7991
+ try {
7992
+ return node_fs.default.readdirSync(dir);
7993
+ } catch {
7994
+ return [];
7995
+ }
7996
+ }
7997
+ function safeRead(path) {
7998
+ try {
7999
+ return node_fs.default.readFileSync(path, "utf8").trim();
8000
+ } catch {
8001
+ return "";
8002
+ }
8003
+ }
8004
+ /** The real filesystem view: `/sys` for enumeration, `/dev` for access. */
8005
+ var nodeCoralFs = {
8006
+ listUsbDevices: () => safeList("/sys/bus/usb/devices"),
8007
+ readUsbAttr: (device, attr) => safeRead(`/sys/bus/usb/devices/${device}/${attr}`),
8008
+ listPciDevices: () => safeList("/sys/bus/pci/devices"),
8009
+ readPciAttr: (device, attr) => safeRead(`/sys/bus/pci/devices/${device}/${attr}`),
8010
+ listApexClass: () => safeList("/sys/class/apex"),
8011
+ canOpen: (path) => {
8012
+ try {
8013
+ node_fs.default.accessSync(path, node_fs.default.constants.R_OK | node_fs.default.constants.W_OK);
8014
+ return true;
8015
+ } catch {
8016
+ return false;
8017
+ }
8018
+ },
8019
+ exists: (path) => {
8020
+ try {
8021
+ return node_fs.default.existsSync(path);
8022
+ } catch {
8023
+ return false;
8024
+ }
8025
+ }
8026
+ };
8027
+ //#endregion
7782
8028
  //#region src/kernel/hwaccel/hwaccel-resolver.ts
7783
8029
  /**
7784
8030
  * Platform-probe for hardware video decode acceleration.
@@ -7803,30 +8049,6 @@ function safeExistsSync(path) {
7803
8049
  return false;
7804
8050
  }
7805
8051
  }
7806
- /**
7807
- * Detect a Coral USB Edge TPU: a matching USB device (`1a6e:089a` pre-init or
7808
- * `18d1:9302` post-init) OR the installed libedgetpu delegate (the hub
7809
- * provisions it out-of-band; its presence is a reliable "Coral is wired"
7810
- * signal even where the container's `/sys` USB view is limited).
7811
- */
7812
- function detectCoralUsb() {
7813
- const CORAL_IDS = [{
7814
- vendor: "1a6e",
7815
- product: "089a"
7816
- }, {
7817
- vendor: "18d1",
7818
- product: "9302"
7819
- }];
7820
- try {
7821
- for (const device of node_fs.readdirSync("/sys/bus/usb/devices")) try {
7822
- const base = `/sys/bus/usb/devices/${device}`;
7823
- const vendor = node_fs.readFileSync(`${base}/idVendor`, "utf8").trim().toLowerCase();
7824
- const product = node_fs.readFileSync(`${base}/idProduct`, "utf8").trim().toLowerCase();
7825
- if (CORAL_IDS.some((id) => id.vendor === vendor && id.product === product)) return true;
7826
- } catch {}
7827
- } catch {}
7828
- return safeExistsSync(process.env["CAMSTACK_EDGETPU_LIB"] ?? "/data/deps/edgetpu/lib/libedgetpu.so.1");
7829
- }
7830
8052
  /** Probe Linux GPU vendors by parsing /proc/bus/pci/devices or /sys/class/drm. */
7831
8053
  function probeLinuxGpus() {
7832
8054
  const signals = {
@@ -7835,7 +8057,7 @@ function probeLinuxGpus() {
7835
8057
  hasIntelGpu: false,
7836
8058
  hasRenderNode: false,
7837
8059
  hasIntelNpu: safeExistsSync("/dev/accel/accel0"),
7838
- hasCoral: detectCoralUsb()
8060
+ coral: classifyCoralAccelerator(nodeCoralFs)
7839
8061
  };
7840
8062
  signals.hasRenderNode = safeExistsSync("/dev/dri/renderD128");
7841
8063
  if (safeExistsSync("/dev/nvidia0") || safeExistsSync("/proc/driver/nvidia/version")) signals.hasNvidiaGpu = true;
@@ -7869,7 +8091,7 @@ function probePlatform() {
7869
8091
  hasIntelGpu: false,
7870
8092
  hasRenderNode: false,
7871
8093
  hasIntelNpu: false,
7872
- hasCoral: safeExistsSync(process.env["CAMSTACK_EDGETPU_LIB"] ?? "/data/deps/edgetpu/lib/libedgetpu.so.1")
8094
+ coral: classifyCoralAccelerator(nodeCoralFs)
7873
8095
  };
7874
8096
  }
7875
8097
  function pickBackendsForPlatform(signals) {
@@ -7960,7 +8182,7 @@ function mapSignalsToInferenceHardware(signals) {
7960
8182
  return {
7961
8183
  gpu: signals.hasNvidiaGpu ? { type: "nvidia" } : signals.hasAmdGpu ? { type: "amd" } : signals.hasIntelGpu ? { type: "intel" } : signals.hasRenderNode ? { type: "intel" } : null,
7962
8184
  npu: signals.platform === "darwin" && signals.arch === "arm64" ? { type: "apple-ane" } : signals.hasIntelNpu ? { type: "intel-npu" } : null,
7963
- coral: signals.hasCoral ? { type: "coral-edgetpu" } : null
8185
+ coral: signals.coral
7964
8186
  };
7965
8187
  }
7966
8188
  /**