@camstack/system 1.2.470 → 1.2.472

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 (93) hide show
  1. package/dist/addon-runner.js +248 -19
  2. package/dist/addon-runner.mjs +249 -20
  3. package/dist/addon-utils.mjs +1 -1
  4. package/dist/{agent-https-DmNQyAl7.mjs → agent-https-JhvY1axF.mjs} +1 -1
  5. package/dist/{agent-https-D_oo3PNv.js → agent-https-bnyFRK7Y.js} +1 -1
  6. package/dist/auth/user-manager.d.ts +2 -2
  7. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  8. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +4 -4
  9. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  10. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +5 -5
  11. package/dist/builtins/alerts/alerts.addon.js +1 -1
  12. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  13. package/dist/builtins/autotrack/index.js +1 -1
  14. package/dist/builtins/autotrack/index.mjs +1 -1
  15. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  16. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +5 -5
  17. package/dist/builtins/calendars/calendars.addon.js +1 -1
  18. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  19. package/dist/builtins/camera-grid/index.js +1 -1
  20. package/dist/builtins/camera-grid/index.mjs +1 -1
  21. package/dist/builtins/composer/composer.addon.js +2 -2
  22. package/dist/builtins/composer/composer.addon.mjs +2 -2
  23. package/dist/builtins/console-logging/index.js +1 -1
  24. package/dist/builtins/console-logging/index.mjs +1 -1
  25. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  26. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  27. package/dist/builtins/device-history/device-history.addon.js +1 -1
  28. package/dist/builtins/device-history/device-history.addon.mjs +1 -1
  29. package/dist/builtins/device-manager/device-manager.addon.js +1 -1
  30. package/dist/builtins/device-manager/device-manager.addon.mjs +1 -1
  31. package/dist/builtins/hub-forwarder/index.js +1 -1
  32. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  33. package/dist/builtins/keychain/index.js +3 -3
  34. package/dist/builtins/keychain/index.mjs +3 -3
  35. package/dist/builtins/liveness-monitor/liveness-monitor.addon.d.ts +9 -25
  36. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +240 -39
  37. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +237 -38
  38. package/dist/builtins/liveness-monitor/liveness-reporter.d.ts +28 -0
  39. package/dist/builtins/liveness-monitor/storage-root-access.d.ts +53 -0
  40. package/dist/builtins/local-auth/local-auth.addon.js +2 -2
  41. package/dist/builtins/local-auth/local-auth.addon.mjs +5 -5
  42. package/dist/builtins/local-network/local-network.addon.js +2 -2
  43. package/dist/builtins/local-network/local-network.addon.mjs +2 -2
  44. package/dist/builtins/loki-logging/index.js +1 -1
  45. package/dist/builtins/loki-logging/index.mjs +1 -1
  46. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  47. package/dist/builtins/native-metrics/native-metrics.addon.mjs +10 -10
  48. package/dist/builtins/platform-probe/coral-accelerators.d.ts +14 -4
  49. package/dist/builtins/platform-probe/index.js +9 -6
  50. package/dist/builtins/platform-probe/index.mjs +15 -12
  51. package/dist/builtins/record-entries/index.js +1 -1
  52. package/dist/builtins/record-entries/index.mjs +1 -1
  53. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  54. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  55. package/dist/builtins/snapshot/index.js +1 -1
  56. package/dist/builtins/snapshot/index.mjs +1 -1
  57. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  58. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +20 -20
  59. package/dist/builtins/sqlite-storage/index.js +1 -1
  60. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  61. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +2 -2
  62. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +2 -2
  63. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  64. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  65. package/dist/builtins/system-config/system-config.addon.js +3 -3
  66. package/dist/builtins/system-config/system-config.addon.mjs +115 -115
  67. package/dist/builtins/winston-logging/index.js +1 -1
  68. package/dist/builtins/winston-logging/index.mjs +1 -1
  69. package/dist/{composition-sources-B0tqvf0t.mjs → composition-sources-BY6rFuAE.mjs} +1 -1
  70. package/dist/{composition-sources-CRJffEiB.js → composition-sources-D3h-tNoJ.js} +1 -1
  71. package/dist/{constants-WF1AqoKF.js → constants-CqbO6e9i.js} +1 -1
  72. package/dist/{constants--A505iuO.mjs → constants-zBiEodEM.mjs} +1 -1
  73. package/dist/{coral-accelerators-Cri32b7q.js → coral-accelerators-BSVsBVzt.js} +46 -11
  74. package/dist/{coral-accelerators-Dl-GnMHn.mjs → coral-accelerators-DBlgWB8k.mjs} +52 -17
  75. package/dist/{custom-action-registry-BGYDjTqY.mjs → custom-action-registry-DZSCLBuT.mjs} +37 -37
  76. package/dist/{device-ca-DYmToMp8.mjs → device-ca-BWTWWBcc.mjs} +1 -1
  77. package/dist/{device-ca-R4MZZtc0.js → device-ca-CfiIg3a9.js} +1 -1
  78. package/dist/{dist-X1r44BdF.mjs → dist-CdFkkmXW.mjs} +6845 -1651
  79. package/dist/{dist-DRL3rEfN.js → dist-DX5Fu3mV.js} +6845 -1651
  80. package/dist/file-host-worker.js +1 -1
  81. package/dist/file-host-worker.mjs +1 -1
  82. package/dist/{hub-mdns-ciao-DUoTS6jN.js → hub-mdns-ciao-C174UDzO.js} +2 -2
  83. package/dist/{hub-mdns-ciao-CZV5Hion.mjs → hub-mdns-ciao-CYp1Gipm.mjs} +2 -2
  84. package/dist/index.js +235 -17
  85. package/dist/index.mjs +453 -235
  86. package/dist/kernel/hwaccel/hwaccel-resolver.d.ts +24 -4
  87. package/dist/kernel/hwaccel/vaapi-init-probe.d.ts +29 -0
  88. package/dist/kernel/moleculer/runner-process-group.d.ts +4 -0
  89. package/dist/{restore-archive-Df6PsOHP.js → restore-archive-B2jIFfu_.js} +1 -1
  90. package/dist/{restore-archive-X0ciGMmO.mjs → restore-archive-BX0gaKtG.mjs} +94 -94
  91. package/dist/{wal-maintenance-DYvzJiuK.js → wal-maintenance-Dxqd5igw.js} +0 -0
  92. package/dist/{wal-maintenance-D6J_MmZ8.mjs → wal-maintenance-KHzJXlF2.mjs} +0 -0
  93. package/package.json +1 -1
@@ -7447,7 +7447,7 @@ function toKebab(name) {
7447
7447
  return name.replace(/[A-Z]/g, (m, i) => (i > 0 ? "-" : "") + m.toLowerCase());
7448
7448
  }
7449
7449
  /**
7450
- * Parse an `op.path` (e.g. `"pipelineExecutor.getDefaultSteps"`) into
7450
+ * Parse an `op.path` (e.g. `"pipelineExecutor.getAvailableEngines"`) into
7451
7451
  * the capability name (kebab-case) and the method name.
7452
7452
  */
7453
7453
  function parsePath(path) {
@@ -7893,14 +7893,34 @@ function currentDelegateHost() {
7893
7893
  override: process.env[_camstack_types_node.EDGETPU_LIB_ENV]
7894
7894
  };
7895
7895
  }
7896
- function countUsbCorals(devices, fsx) {
7897
- let count = 0;
7896
+ /** usbfs names a device `/dev/bus/usb/<busnum>/<devnum>`, each zero-padded to three digits. */
7897
+ function usbDeviceNode(device, fsx) {
7898
+ const bus = Number.parseInt(fsx.readUsbAttr(device, "busnum"), 10);
7899
+ const dev = Number.parseInt(fsx.readUsbAttr(device, "devnum"), 10);
7900
+ if (!Number.isInteger(bus) || !Number.isInteger(dev) || bus <= 0 || dev <= 0) return null;
7901
+ return `/dev/bus/usb/${String(bus).padStart(3, "0")}/${String(dev).padStart(3, "0")}`;
7902
+ }
7903
+ /**
7904
+ * USB units: sysfs is the HOST's view — a container whose `/dev/bus/usb`
7905
+ * mapping was removed still lists the stick under `/sys/bus/usb/devices`. A
7906
+ * listed Coral is usable only when its usbfs device node is in this process's
7907
+ * view AND opens read/write; otherwise it is present but not accessible.
7908
+ */
7909
+ function classifyUsb(devices, fsx) {
7910
+ let usable = 0;
7911
+ const inaccessibleNodes = [];
7898
7912
  for (const device of devices) {
7899
7913
  const vendor = fsx.readUsbAttr(device, "idVendor").toLowerCase();
7900
7914
  const product = fsx.readUsbAttr(device, "idProduct").toLowerCase();
7901
- if (CORAL_USB_IDS.some((id) => id.vendor === vendor && id.product === product)) count++;
7915
+ if (!CORAL_USB_IDS.some((id) => id.vendor === vendor && id.product === product)) continue;
7916
+ const node = usbDeviceNode(device, fsx);
7917
+ if (node !== null && fsx.exists(node) && fsx.canOpen(node)) usable++;
7918
+ else inaccessibleNodes.push(node ?? `/sys/bus/usb/devices/${device}`);
7902
7919
  }
7903
- return count;
7920
+ return {
7921
+ usable,
7922
+ inaccessibleNodes
7923
+ };
7904
7924
  }
7905
7925
  function countPciCorals(fsx) {
7906
7926
  let count = 0;
@@ -7943,7 +7963,9 @@ function classifyCoralAccelerator(fsx, delegateHost = currentDelegateHost()) {
7943
7963
  /**
7944
7964
  * Detect Coral Edge TPUs on USB and PCIe/M.2, with the evidence that decided.
7945
7965
  *
7946
- * - USB: every matching USB device counts (multiple Corals run concurrently).
7966
+ * - USB: every matching USB device counts (multiple Corals run concurrently),
7967
+ * usable only if its `/dev/bus/usb/<BBB>/<DDD>` node opens read/write — a
7968
+ * listed stick whose node is missing or refused is `device-not-accessible`.
7947
7969
  * - PCIe: the apex driver's units, each usable only if its device node opens;
7948
7970
  * a Coral PCI function the driver did not bind is `driver-missing`.
7949
7971
  * - Fallback: when the USB bus is NOT OBSERVABLE (`/sys/bus/usb/devices`
@@ -7960,18 +7982,28 @@ function classifyCoralAccelerator(fsx, delegateHost = currentDelegateHost()) {
7960
7982
  function detectCoralAccelerator(fsx, delegateHost = currentDelegateHost()) {
7961
7983
  const usbDevices = fsx.listUsbDevices();
7962
7984
  const usbBus = usbDevices !== null && usbDevices.length > 0 ? "observed" : "unobservable";
7963
- const usb = usbDevices === null ? 0 : countUsbCorals(usbDevices, fsx);
7985
+ const usb = usbDevices === null ? {
7986
+ usable: 0,
7987
+ inaccessibleNodes: []
7988
+ } : classifyUsb(usbDevices, fsx);
7989
+ const usbSeen = usb.usable + usb.inaccessibleNodes.length;
7990
+ const inaccessibleUsbNodes = usb.inaccessibleNodes;
7964
7991
  const pci = classifyPci(fsx);
7965
7992
  const units = [];
7966
- if (usb > 0) units.push({
7993
+ if (usb.usable > 0) units.push({
7967
7994
  bus: "usb",
7968
- count: usb
7995
+ count: usb.usable
7969
7996
  });
7970
7997
  if (pci.usable > 0) units.push({
7971
7998
  bus: "pci",
7972
7999
  count: pci.usable
7973
8000
  });
7974
8001
  const unavailable = [];
8002
+ if (usb.inaccessibleNodes.length > 0) unavailable.push({
8003
+ bus: "usb",
8004
+ count: usb.inaccessibleNodes.length,
8005
+ reason: "device-not-accessible"
8006
+ });
7975
8007
  if (pci.driverMissing > 0) unavailable.push({
7976
8008
  bus: "pci",
7977
8009
  count: pci.driverMissing,
@@ -7992,7 +8024,8 @@ function detectCoralAccelerator(fsx, delegateHost = currentDelegateHost()) {
7992
8024
  units
7993
8025
  },
7994
8026
  usbBus,
7995
- decidedBy: usb > 0 ? "usb-ids" : "pci"
8027
+ decidedBy: usbSeen > 0 ? "usb-ids" : "pci",
8028
+ inaccessibleUsbNodes
7996
8029
  };
7997
8030
  if (usbBus === "unobservable" && (0, _camstack_types_node.chooseEdgetpuDelegate)({
7998
8031
  ...delegateHost,
@@ -8006,12 +8039,14 @@ function detectCoralAccelerator(fsx, delegateHost = currentDelegateHost()) {
8006
8039
  }]
8007
8040
  },
8008
8041
  usbBus,
8009
- decidedBy: "delegate-fallback"
8042
+ decidedBy: "delegate-fallback",
8043
+ inaccessibleUsbNodes
8010
8044
  };
8011
8045
  return {
8012
8046
  info: null,
8013
8047
  usbBus,
8014
- decidedBy: "none"
8048
+ decidedBy: "none",
8049
+ inaccessibleUsbNodes
8015
8050
  };
8016
8051
  }
8017
8052
  function safeListOrNull(dir) {
@@ -8059,6 +8094,148 @@ var nodeCoralFs = {
8059
8094
  }
8060
8095
  };
8061
8096
  //#endregion
8097
+ //#region src/kernel/hwaccel/vaapi-init-probe.ts
8098
+ /**
8099
+ * Can libva initialise the VA driver on this node's render node? (D926)
8100
+ *
8101
+ * Measured 2026-10-23 (intel-1.2.509, hub + little-unraid): Intel's iHD 25.2.4
8102
+ * exports only `__vaDriverInit_1_22`, the container's Ubuntu libva 2.20 looks
8103
+ * for `_1_20`, and `vaInitialize` failed — while the resolver kept offering
8104
+ * `qsv, vaapi`. Every session tried, failed and fell back to software: 722
8105
+ * `hwaccel 'vaapi' failed` lines a day and nothing that named the cause.
8106
+ *
8107
+ * One `vainfo --display drm --device <node>` per process answers it. A failure
8108
+ * reads the driver's exported `__vaDriverInit_1_N` so the verdict names the gap
8109
+ * (`driver iHD needs VA-API >= 1.22, libva has 1.20`). No `vainfo` on the host
8110
+ * (a bare install) is `unknown` — the resolver then behaves as it always did.
8111
+ */
8112
+ var VAINFO_TIMEOUT_MS = 1e4;
8113
+ var INIT_SYMBOL = /__vaDriverInit_(\d+)_(\d+)/g;
8114
+ var VA_API_VERSION = /VA-API version:? (\d+)\.(\d+)/;
8115
+ var DRIVER_OPEN = /Trying to open (\S+_drv_video\.so)/g;
8116
+ function newestInitVersion(symbols) {
8117
+ let best = null;
8118
+ for (const symbol of symbols) for (const m of symbol.matchAll(INIT_SYMBOL)) {
8119
+ const v = {
8120
+ major: Number(m[1]),
8121
+ minor: Number(m[2])
8122
+ };
8123
+ if (!best || v.major > best.major || v.major === best.major && v.minor > best.minor) best = v;
8124
+ }
8125
+ return best;
8126
+ }
8127
+ function lastMatch(text, re) {
8128
+ let last = null;
8129
+ for (const m of text.matchAll(re)) last = m[1] ?? null;
8130
+ return last;
8131
+ }
8132
+ function lastLine(text) {
8133
+ const lines = text.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
8134
+ return lines[lines.length - 1] ?? "no output";
8135
+ }
8136
+ function driverName(driverPath) {
8137
+ if (!driverPath) return "unknown";
8138
+ return (0, node_path.basename)(driverPath).replace(/_drv_video\.so$/, "");
8139
+ }
8140
+ /** Classify one vainfo run plus the driver's exported init symbols. Pure. */
8141
+ function classifyVainfo(run, driverSymbols) {
8142
+ const va = VA_API_VERSION.exec(run.output);
8143
+ const vaApiVersion = va ? `${va[1]}.${va[2]}` : null;
8144
+ const driverPath = lastMatch(run.output, DRIVER_OPEN);
8145
+ const needs = newestInitVersion(driverSymbols);
8146
+ const driverNeedsVaApi = needs ? `${needs.major}.${needs.minor}` : null;
8147
+ const base = {
8148
+ vaApiVersion,
8149
+ driverPath,
8150
+ driverNeedsVaApi
8151
+ };
8152
+ if (run.spawnError !== null) return {
8153
+ ...base,
8154
+ state: "unknown",
8155
+ summary: `vaapi: unknown (vainfo not run: ${run.spawnError})`
8156
+ };
8157
+ if (run.exitCode === 0) return {
8158
+ ...base,
8159
+ state: "ok",
8160
+ summary: `vaapi: ok (VA-API ${vaApiVersion ?? "?"}, driver ${driverName(driverPath)})`
8161
+ };
8162
+ const reason = needs !== null && va !== null && (needs.major > Number(va[1]) || needs.major === Number(va[1]) && needs.minor > Number(va[2])) ? `driver ${driverName(driverPath)} needs VA-API >= ${driverNeedsVaApi}, libva has ${vaApiVersion}` : lastLine(run.output);
8163
+ return {
8164
+ ...base,
8165
+ state: "init-failed",
8166
+ summary: `vaapi: init-failed (${reason})`
8167
+ };
8168
+ }
8169
+ /** Run `vainfo` against one render node; never throws. */
8170
+ function runVainfo(renderNode) {
8171
+ return new Promise((resolve) => {
8172
+ (0, node_child_process.execFile)("vainfo", [
8173
+ "--display",
8174
+ "drm",
8175
+ "--device",
8176
+ renderNode
8177
+ ], {
8178
+ timeout: VAINFO_TIMEOUT_MS,
8179
+ encoding: "utf8"
8180
+ }, (err, stdout, stderr) => {
8181
+ const output = `${stdout}\n${stderr}`;
8182
+ if (err === null) {
8183
+ resolve({
8184
+ exitCode: 0,
8185
+ output,
8186
+ spawnError: null
8187
+ });
8188
+ return;
8189
+ }
8190
+ const code = err.code;
8191
+ if (typeof code === "number") {
8192
+ resolve({
8193
+ exitCode: code,
8194
+ output,
8195
+ spawnError: null
8196
+ });
8197
+ return;
8198
+ }
8199
+ resolve({
8200
+ exitCode: null,
8201
+ output,
8202
+ spawnError: code ?? (err.killed ? "timeout" : err.message)
8203
+ });
8204
+ });
8205
+ });
8206
+ }
8207
+ /**
8208
+ * The `__vaDriverInit_N_M` names in a driver file, streamed (iHD is ~43 MB),
8209
+ * with an overlap so a name split across two chunks is still found.
8210
+ */
8211
+ function readDriverInitSymbols(driverPath) {
8212
+ return new Promise((resolve) => {
8213
+ const found = /* @__PURE__ */ new Set();
8214
+ let carry = "";
8215
+ const stream = (0, node_fs.createReadStream)(driverPath, {
8216
+ encoding: "latin1",
8217
+ highWaterMark: 64 * 1024
8218
+ });
8219
+ stream.on("data", (chunk) => {
8220
+ const text = carry + String(chunk);
8221
+ for (const m of text.matchAll(INIT_SYMBOL)) if (m.index + m[0].length < text.length) found.add(m[0]);
8222
+ carry = text.slice(-32);
8223
+ });
8224
+ stream.on("error", () => resolve([]));
8225
+ stream.on("end", () => {
8226
+ for (const m of carry.matchAll(INIT_SYMBOL)) found.add(m[0]);
8227
+ resolve([...found].sort());
8228
+ });
8229
+ });
8230
+ }
8231
+ /** Probe one render node: vainfo, and on failure the driver's init symbols. */
8232
+ async function probeVaapiInit(renderNode) {
8233
+ const run = await runVainfo(renderNode);
8234
+ if (run.spawnError !== null || run.exitCode === 0) return classifyVainfo(run, []);
8235
+ const driverPath = lastMatch(run.output, DRIVER_OPEN);
8236
+ return classifyVainfo(run, driverPath ? await readDriverInitSymbols(driverPath) : []);
8237
+ }
8238
+ //#endregion
8062
8239
  //#region src/kernel/hwaccel/hwaccel-resolver.ts
8063
8240
  /**
8064
8241
  * Platform-probe for hardware video decode acceleration.
@@ -8128,7 +8305,23 @@ function probePlatform() {
8128
8305
  coral: classifyCoralAccelerator(nodeCoralFs)
8129
8306
  };
8130
8307
  }
8131
- function pickBackendsForPlatform(signals) {
8308
+ /** The backends that open their device through libva on Linux. */
8309
+ var LIBVA_BACKENDS = ["vaapi", "qsv"];
8310
+ /**
8311
+ * The preference list for these signals. A `vaapi` verdict of `init-failed`
8312
+ * (libva cannot initialise the driver — D926) removes every libva-backed
8313
+ * backend and names the cause in the rationale; `ok`, `unknown` or `null`
8314
+ * change nothing.
8315
+ */
8316
+ function pickBackendsForPlatform(signals, vaapi = null) {
8317
+ const res = pickBackendsFromSignals(signals);
8318
+ if (signals.platform !== "linux" || vaapi?.state !== "init-failed") return res;
8319
+ return {
8320
+ preferred: res.preferred.filter((b) => !LIBVA_BACKENDS.includes(b)),
8321
+ rationale: `${res.rationale} ${vaapi.summary} — vaapi/qsv withheld, decode runs in software.`
8322
+ };
8323
+ }
8324
+ function pickBackendsFromSignals(signals) {
8132
8325
  switch (signals.platform) {
8133
8326
  case "darwin": return {
8134
8327
  preferred: ["videotoolbox"],
@@ -8189,13 +8382,49 @@ function resolveHwAccel(prefer) {
8189
8382
  };
8190
8383
  return pickBackendsForPlatform(probePlatform());
8191
8384
  }
8385
+ var RENDER_NODE = "/dev/dri/renderD128";
8386
+ /** Process-wide: the VA init failure is logged once per process, not per resolver. */
8387
+ var PROCESS_VAAPI_REPORT = { reported: false };
8388
+ /** Process-wide: hub-main builds one resolver per in-process addon; vainfo runs once. */
8389
+ var PROCESS_VAAPI_PROBES = /* @__PURE__ */ new Map();
8390
+ function probeVaapiOncePerProcess(renderNode) {
8391
+ const known = PROCESS_VAAPI_PROBES.get(renderNode);
8392
+ if (known) return known;
8393
+ const probe = probeVaapiInit(renderNode);
8394
+ PROCESS_VAAPI_PROBES.set(renderNode, probe);
8395
+ return probe;
8396
+ }
8192
8397
  /**
8193
8398
  * Build the `IKernelHwAccel` provider used to populate `ctx.kernel.hwaccel`.
8194
- * Thin async wrapper around the sync `resolveHwAccel` function so the
8195
- * contract matches the per-node `$hwaccel.resolve` Moleculer action.
8196
- */
8197
- function createKernelHwAccel() {
8198
- return { resolve: async (prefer) => resolveHwAccel(prefer) };
8399
+ * An auto resolve on a Linux host with a render node asks libva ONCE per
8400
+ * provider whether it can initialise the driver (D926); an explicit override
8401
+ * is never second-guessed.
8402
+ */
8403
+ function createKernelHwAccel(options = {}) {
8404
+ const probeSignals = options.probeSignals ?? probePlatform;
8405
+ const probeVaapi = options.probeVaapi ?? probeVaapiOncePerProcess;
8406
+ const reportOnce = options.reportOnce ?? PROCESS_VAAPI_REPORT;
8407
+ let vaapi = null;
8408
+ const vaapiVerdict = async () => {
8409
+ if (vaapi === null) vaapi = probeVaapi(RENDER_NODE);
8410
+ const status = await vaapi;
8411
+ if (status.state === "init-failed" && !reportOnce.reported) {
8412
+ reportOnce.reported = true;
8413
+ options.logger?.error(`hwaccel: ${status.summary} — vaapi/qsv withheld, decode runs in software`, { meta: {
8414
+ renderNode: RENDER_NODE,
8415
+ vaApiVersion: status.vaApiVersion,
8416
+ driverPath: status.driverPath,
8417
+ driverNeedsVaApi: status.driverNeedsVaApi
8418
+ } });
8419
+ }
8420
+ return status;
8421
+ };
8422
+ return { resolve: async (prefer) => {
8423
+ if (prefer === "none" || prefer !== null && prefer !== void 0 && prefer.length > 0) return resolveHwAccel(prefer);
8424
+ const signals = probeSignals();
8425
+ if (signals.platform !== "linux" || !signals.hasRenderNode) return pickBackendsForPlatform(signals);
8426
+ return pickBackendsForPlatform(signals, await vaapiVerdict());
8427
+ } };
8199
8428
  }
8200
8429
  //#endregion
8201
8430
  //#region src/kernel/inference/inference-resolver.ts
@@ -10540,7 +10769,7 @@ async function buildAddonContext(runtime, declaration, dataDir, options) {
10540
10769
  value
10541
10770
  })
10542
10771
  };
10543
- const hwaccel = createKernelHwAccel();
10772
+ const hwaccel = createKernelHwAccel({ logger: scopedLogger });
10544
10773
  const inferenceEngine = createKernelInferenceEngine();
10545
10774
  return {
10546
10775
  localNodeId: nodeId,