@camstack/system 1.0.2

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 (262) hide show
  1. package/dist/addon/addon-api-factory.d.ts +35 -0
  2. package/dist/addon-routes/addon-route-registry.d.ts +37 -0
  3. package/dist/addon-runner.js +599 -0
  4. package/dist/addon-runner.mjs +597 -0
  5. package/dist/auth/api-key-manager.d.ts +26 -0
  6. package/dist/auth/auth-manager.d.ts +109 -0
  7. package/dist/auth/parse-record.d.ts +18 -0
  8. package/dist/auth/scope-matcher.d.ts +7 -0
  9. package/dist/auth/scoped-token-manager.d.ts +40 -0
  10. package/dist/auth/totp-manager.d.ts +51 -0
  11. package/dist/auth/user-manager.d.ts +34 -0
  12. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.d.ts +53 -0
  13. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +259 -0
  14. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +251 -0
  15. package/dist/builtins/addon-pages-aggregator/dedupe-pages.d.ts +6 -0
  16. package/dist/builtins/addon-pages-aggregator/index.d.ts +1 -0
  17. package/dist/builtins/addon-pages-aggregator/index.js +8 -0
  18. package/dist/builtins/addon-pages-aggregator/index.mjs +2 -0
  19. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.d.ts +47 -0
  20. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +228 -0
  21. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +220 -0
  22. package/dist/builtins/addon-widgets-aggregator/index.d.ts +1 -0
  23. package/dist/builtins/addon-widgets-aggregator/index.js +8 -0
  24. package/dist/builtins/addon-widgets-aggregator/index.mjs +2 -0
  25. package/dist/builtins/alerts/alerts.addon.d.ts +81 -0
  26. package/dist/builtins/alerts/alerts.addon.js +601 -0
  27. package/dist/builtins/alerts/alerts.addon.mjs +595 -0
  28. package/dist/builtins/alerts/index.d.ts +1 -0
  29. package/dist/builtins/alerts/index.js +4 -0
  30. package/dist/builtins/alerts/index.mjs +2 -0
  31. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +147 -0
  32. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2229 -0
  33. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2220 -0
  34. package/dist/builtins/backup-orchestrator/cron-helpers.d.ts +23 -0
  35. package/dist/builtins/backup-orchestrator/destination-policy.d.ts +72 -0
  36. package/dist/builtins/backup-orchestrator/download-helpers.d.ts +12 -0
  37. package/dist/builtins/backup-orchestrator/index.d.ts +2 -0
  38. package/dist/builtins/backup-orchestrator/index.js +8 -0
  39. package/dist/builtins/backup-orchestrator/index.mjs +2 -0
  40. package/dist/builtins/backup-orchestrator/manifest-store.d.ts +77 -0
  41. package/dist/builtins/console-logging/console-destination.d.ts +13 -0
  42. package/dist/builtins/console-logging/console-logging.addon.d.ts +25 -0
  43. package/dist/builtins/console-logging/index.d.ts +3 -0
  44. package/dist/builtins/console-logging/index.js +104 -0
  45. package/dist/builtins/console-logging/index.mjs +95 -0
  46. package/dist/builtins/device-manager/device-config-contribution.d.ts +32 -0
  47. package/dist/builtins/device-manager/device-event-propagator.d.ts +26 -0
  48. package/dist/builtins/device-manager/device-link-overlay.d.ts +23 -0
  49. package/dist/builtins/device-manager/device-link-resolver.d.ts +15 -0
  50. package/dist/builtins/device-manager/device-manager.addon.d.ts +452 -0
  51. package/dist/builtins/device-manager/device-manager.addon.js +3299 -0
  52. package/dist/builtins/device-manager/device-manager.addon.mjs +3292 -0
  53. package/dist/builtins/device-manager/index.d.ts +2 -0
  54. package/dist/builtins/device-manager/index.js +8 -0
  55. package/dist/builtins/device-manager/index.mjs +2 -0
  56. package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts +44 -0
  57. package/dist/builtins/hub-forwarder/hub-forwarder.addon.d.ts +15 -0
  58. package/dist/builtins/hub-forwarder/index.d.ts +3 -0
  59. package/dist/builtins/hub-forwarder/index.js +154 -0
  60. package/dist/builtins/hub-forwarder/index.mjs +145 -0
  61. package/dist/builtins/local-auth/auth-schema.d.ts +26 -0
  62. package/dist/builtins/local-auth/index.d.ts +1 -0
  63. package/dist/builtins/local-auth/index.js +4 -0
  64. package/dist/builtins/local-auth/index.mjs +2 -0
  65. package/dist/builtins/local-auth/local-auth.addon.d.ts +18 -0
  66. package/dist/builtins/local-auth/local-auth.addon.js +8094 -0
  67. package/dist/builtins/local-auth/local-auth.addon.mjs +8063 -0
  68. package/dist/builtins/local-auth/oauth-grants.d.ts +45 -0
  69. package/dist/builtins/local-auth/oauth-session-manager.d.ts +50 -0
  70. package/dist/builtins/local-network/index.d.ts +2 -0
  71. package/dist/builtins/local-network/index.js +10 -0
  72. package/dist/builtins/local-network/index.mjs +2 -0
  73. package/dist/builtins/local-network/local-network.addon.d.ts +150 -0
  74. package/dist/builtins/local-network/local-network.addon.js +489 -0
  75. package/dist/builtins/local-network/local-network.addon.mjs +477 -0
  76. package/dist/builtins/native-metrics/index.d.ts +2 -0
  77. package/dist/builtins/native-metrics/native-metrics-provider.d.ts +48 -0
  78. package/dist/builtins/native-metrics/native-metrics.addon.d.ts +73 -0
  79. package/dist/builtins/native-metrics/native-metrics.addon.js +922 -0
  80. package/dist/builtins/native-metrics/native-metrics.addon.mjs +914 -0
  81. package/dist/builtins/platform-probe/hardware-decode-accel-probe.d.ts +37 -0
  82. package/dist/builtins/platform-probe/hardware-encoder-probe.d.ts +13 -0
  83. package/dist/builtins/platform-probe/index.d.ts +22 -0
  84. package/dist/builtins/platform-probe/index.js +834 -0
  85. package/dist/builtins/platform-probe/index.mjs +822 -0
  86. package/dist/builtins/platform-probe/inference-config-resolver.d.ts +29 -0
  87. package/dist/builtins/platform-probe/intel-accelerators.d.ts +11 -0
  88. package/dist/builtins/platform-probe/platform-scorer.d.ts +30 -0
  89. package/dist/builtins/platform-probe/runtime-packages.d.ts +6 -0
  90. package/dist/builtins/remote-access-orchestrator/enabled-providers-reconcile.d.ts +96 -0
  91. package/dist/builtins/remote-access-orchestrator/index.d.ts +1 -0
  92. package/dist/builtins/remote-access-orchestrator/index.js +8 -0
  93. package/dist/builtins/remote-access-orchestrator/index.mjs +2 -0
  94. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.d.ts +40 -0
  95. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +214 -0
  96. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +208 -0
  97. package/dist/builtins/shared/settle-sources.d.ts +22 -0
  98. package/dist/builtins/snapshot/index.d.ts +2 -0
  99. package/dist/builtins/snapshot/index.js +494 -0
  100. package/dist/builtins/snapshot/index.mjs +488 -0
  101. package/dist/builtins/snapshot/snapshot.addon.d.ts +120 -0
  102. package/dist/builtins/sqlite-storage/config-store.d.ts +8 -0
  103. package/dist/builtins/sqlite-storage/device-store.d.ts +23 -0
  104. package/dist/builtins/sqlite-storage/filesystem-browse-provider.d.ts +25 -0
  105. package/dist/builtins/sqlite-storage/filesystem-storage-provider.d.ts +83 -0
  106. package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.ts +32 -0
  107. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +396 -0
  108. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +388 -0
  109. package/dist/builtins/sqlite-storage/index.d.ts +8 -0
  110. package/dist/builtins/sqlite-storage/index.js +62 -0
  111. package/dist/builtins/sqlite-storage/index.mjs +49 -0
  112. package/dist/builtins/sqlite-storage/integration-registry.d.ts +27 -0
  113. package/dist/builtins/sqlite-storage/path-guard.d.ts +4 -0
  114. package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +102 -0
  115. package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +14 -0
  116. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +644 -0
  117. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +636 -0
  118. package/dist/builtins/storage-orchestrator/index.d.ts +6 -0
  119. package/dist/builtins/storage-orchestrator/index.js +10 -0
  120. package/dist/builtins/storage-orchestrator/index.mjs +2 -0
  121. package/dist/builtins/storage-orchestrator/location-store.d.ts +49 -0
  122. package/dist/builtins/storage-orchestrator/provider-discovery.d.ts +10 -0
  123. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +103 -0
  124. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1138 -0
  125. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1128 -0
  126. package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +236 -0
  127. package/dist/builtins/storage-orchestrator/storage-pressure-manager.d.ts +38 -0
  128. package/dist/builtins/system-backup/system-backup.service.d.ts +137 -0
  129. package/dist/builtins/system-config/index.d.ts +1 -0
  130. package/dist/builtins/system-config/index.js +8 -0
  131. package/dist/builtins/system-config/index.mjs +2 -0
  132. package/dist/builtins/system-config/system-config.addon.d.ts +10 -0
  133. package/dist/builtins/system-config/system-config.addon.js +232 -0
  134. package/dist/builtins/system-config/system-config.addon.mjs +226 -0
  135. package/dist/builtins/winston-logging/index.d.ts +3 -0
  136. package/dist/builtins/winston-logging/index.js +156 -0
  137. package/dist/builtins/winston-logging/index.mjs +144 -0
  138. package/dist/builtins/winston-logging/winston-destination.d.ts +21 -0
  139. package/dist/builtins/winston-logging/winston-logging.addon.d.ts +19 -0
  140. package/dist/chunk-CNf5ZN-e.mjs +37 -0
  141. package/dist/chunk-Cek0wNdY.js +64 -0
  142. package/dist/download/model-download-service.d.ts +41 -0
  143. package/dist/download/model-downloader.d.ts +31 -0
  144. package/dist/events/event-bus.d.ts +10 -0
  145. package/dist/events/system-event-bus.d.ts +14 -0
  146. package/dist/feature/feature-manager.d.ts +11 -0
  147. package/dist/formatter-B7qW8bPJ.mjs +162 -0
  148. package/dist/formatter-DqAKDlvN.js +167 -0
  149. package/dist/http/authenticated-file-server.d.ts +53 -0
  150. package/dist/http/data-plane-registry.d.ts +23 -0
  151. package/dist/http/file-data-plane.d.ts +10 -0
  152. package/dist/http/reverse-proxy.d.ts +15 -0
  153. package/dist/index.d.ts +82 -0
  154. package/dist/index.js +93485 -0
  155. package/dist/index.mjs +93179 -0
  156. package/dist/intel-accelerators-Gg0P5mnl.js +20 -0
  157. package/dist/intel-accelerators-hGgpZ0pX.mjs +19 -0
  158. package/dist/kernel/addon-class-resolver.d.ts +4 -0
  159. package/dist/kernel/addon-engine-manager.d.ts +22 -0
  160. package/dist/kernel/addon-health-monitor.d.ts +154 -0
  161. package/dist/kernel/addon-installer.d.ts +208 -0
  162. package/dist/kernel/addon-loader.d.ts +106 -0
  163. package/dist/kernel/addon-manifest.d.ts +77 -0
  164. package/dist/kernel/capability-handle.d.ts +46 -0
  165. package/dist/kernel/capability-registry.d.ts +412 -0
  166. package/dist/kernel/config-manager.d.ts +212 -0
  167. package/dist/kernel/config-schema.d.ts +93 -0
  168. package/dist/kernel/custom-action-registry.d.ts +23 -0
  169. package/dist/kernel/deps/addon-deps-manager.d.ts +19 -0
  170. package/dist/kernel/deps/manifest-native-deps.d.ts +25 -0
  171. package/dist/kernel/deps/manifest-python-deps.d.ts +20 -0
  172. package/dist/kernel/device-registry.d.ts +29 -0
  173. package/dist/kernel/fs-utils.d.ts +41 -0
  174. package/dist/kernel/hwaccel/hwaccel-resolver.d.ts +19 -0
  175. package/dist/kernel/hwaccel/hwaccel-service.d.ts +4 -0
  176. package/dist/kernel/index.d.ts +74 -0
  177. package/dist/kernel/infra-capabilities.d.ts +13 -0
  178. package/dist/kernel/moleculer/addon-context-factory.d.ts +91 -0
  179. package/dist/kernel/moleculer/addon-data-plane-facility.d.ts +19 -0
  180. package/dist/kernel/moleculer/addon-runner.d.ts +1 -0
  181. package/dist/kernel/moleculer/addon-service-factory.d.ts +50 -0
  182. package/dist/kernel/moleculer/broker-factory.d.ts +50 -0
  183. package/dist/kernel/moleculer/cap-usage-registry.d.ts +46 -0
  184. package/dist/kernel/moleculer/capabilities-access.d.ts +21 -0
  185. package/dist/kernel/moleculer/child-addon-call-dispatch.d.ts +46 -0
  186. package/dist/kernel/moleculer/child-cap-dispatch.d.ts +20 -0
  187. package/dist/kernel/moleculer/cluster-secret.d.ts +15 -0
  188. package/dist/kernel/moleculer/core-cap-service.d.ts +50 -0
  189. package/dist/kernel/moleculer/crash-supervisor.d.ts +50 -0
  190. package/dist/kernel/moleculer/device-cap-proxy.d.ts +79 -0
  191. package/dist/kernel/moleculer/event-bus-core.d.ts +53 -0
  192. package/dist/kernel/moleculer/event-bus.d.ts +53 -0
  193. package/dist/kernel/moleculer/hub-log-forwarder.d.ts +36 -0
  194. package/dist/kernel/moleculer/hub-service.d.ts +35 -0
  195. package/dist/kernel/moleculer/node-registry.d.ts +126 -0
  196. package/dist/kernel/moleculer/process-context.d.ts +4 -0
  197. package/dist/kernel/moleculer/process-service.d.ts +72 -0
  198. package/dist/kernel/moleculer/provider-registry.d.ts +28 -0
  199. package/dist/kernel/moleculer/readiness-context.d.ts +62 -0
  200. package/dist/kernel/moleculer/readiness-service.d.ts +7 -0
  201. package/dist/kernel/moleculer/register-node-client.d.ts +35 -0
  202. package/dist/kernel/moleculer/remote-logger.d.ts +43 -0
  203. package/dist/kernel/moleculer/resilient-cap-call.d.ts +28 -0
  204. package/dist/kernel/moleculer/stream-probe-service.d.ts +9 -0
  205. package/dist/kernel/moleculer/trpc-links.d.ts +189 -0
  206. package/dist/kernel/moleculer/typed-array-serde.d.ts +25 -0
  207. package/dist/kernel/moleculer/worker-device-restore.d.ts +10 -0
  208. package/dist/kernel/provider-kind-drift.d.ts +12 -0
  209. package/dist/kernel/restart-coordinator.d.ts +90 -0
  210. package/dist/kernel/storage-location-registry.d.ts +40 -0
  211. package/dist/kernel/transport/cap-action-name.d.ts +100 -0
  212. package/dist/kernel/transport/cap-route-resolver.d.ts +148 -0
  213. package/dist/kernel/transport/cap-route.d.ts +148 -0
  214. package/dist/kernel/transport/child-cap-protocol.d.ts +136 -0
  215. package/dist/kernel/transport/create-local-transport.d.ts +7 -0
  216. package/dist/kernel/transport/frame-codec.d.ts +7 -0
  217. package/dist/kernel/transport/index.d.ts +27 -0
  218. package/dist/kernel/transport/local-child-client.d.ts +136 -0
  219. package/dist/kernel/transport/local-child-registry.d.ts +179 -0
  220. package/dist/kernel/transport/local-endpoint-path.d.ts +6 -0
  221. package/dist/kernel/transport/local-transport.d.ts +46 -0
  222. package/dist/kernel/transport/parent-unowned-call.d.ts +75 -0
  223. package/dist/kernel/transport/socket-channel.d.ts +27 -0
  224. package/dist/kernel/transport/uds-event-bridge.d.ts +36 -0
  225. package/dist/kernel/transport/uds-event-bus.d.ts +22 -0
  226. package/dist/kernel/transport/uds-local-transport.d.ts +18 -0
  227. package/dist/kernel/transport/uds-log-ingest.d.ts +28 -0
  228. package/dist/kernel/transport/uds-logger.d.ts +44 -0
  229. package/dist/kernel/utils/ring-buffer.d.ts +15 -0
  230. package/dist/kernel/workspace-detect.d.ts +9 -0
  231. package/dist/lifecycle/lifecycle-state-machine.d.ts +28 -0
  232. package/dist/logging/formatter.d.ts +30 -0
  233. package/dist/logging/log-manager.d.ts +54 -0
  234. package/dist/logging/log-ring-buffer.d.ts +47 -0
  235. package/dist/logging/partitioned-log-buffer.d.ts +35 -0
  236. package/dist/logging/scoped-logger.d.ts +17 -0
  237. package/dist/main-DNnMW7Z2.js +9983 -0
  238. package/dist/main-rtjOwPBR.mjs +9976 -0
  239. package/dist/manifest-python-deps-D1DbAQEv.js +6724 -0
  240. package/dist/manifest-python-deps-DZsKTbs1.mjs +6315 -0
  241. package/dist/network/network-quality.d.ts +11 -0
  242. package/dist/notification/notification-service.d.ts +37 -0
  243. package/dist/notification/toast-service.d.ts +22 -0
  244. package/dist/pipeline/engine-manager-resolver.d.ts +15 -0
  245. package/dist/pipeline/pipeline-runner.d.ts +8 -0
  246. package/dist/pipeline/pipeline-validator.d.ts +13 -0
  247. package/dist/process/resource-monitor.d.ts +11 -0
  248. package/dist/python/python-env-manager.d.ts +12 -0
  249. package/dist/repl/interfaces.d.ts +31 -0
  250. package/dist/repl/repl-engine.d.ts +8 -0
  251. package/dist/resource-monitor-ClDGFyf6.mjs +57 -0
  252. package/dist/resource-monitor-IIEanuJt.js +74 -0
  253. package/dist/settle-sources-Bhsy57y-.js +38 -0
  254. package/dist/settle-sources-CDtNC8ub.mjs +33 -0
  255. package/dist/storage/fs-storage-backend.d.ts +40 -0
  256. package/dist/storage/storage-location-manager.d.ts +23 -0
  257. package/dist/storage/storage-manager.d.ts +83 -0
  258. package/dist/tar-BgAEMRBR.js +5434 -0
  259. package/dist/tar-ByMOPNM0.mjs +5429 -0
  260. package/dist/tls/cert-manager.d.ts +26 -0
  261. package/dist/tls/index.d.ts +1 -0
  262. package/package.json +343 -0
@@ -0,0 +1,834 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ const require_chunk = require("../../chunk-Cek0wNdY.js");
6
+ let node_fs = require("node:fs");
7
+ node_fs = require_chunk.__toESM(node_fs);
8
+ let _camstack_types = require("@camstack/types");
9
+ let node_child_process = require("node:child_process");
10
+ let node_util = require("node:util");
11
+ let node_os = require("node:os");
12
+ node_os = require_chunk.__toESM(node_os);
13
+ //#region src/builtins/platform-probe/platform-scorer.ts
14
+ /**
15
+ * Promisified `execFile`. Used across the scorer so every subprocess
16
+ * spawn yields the event loop — critical at boot because a single sync
17
+ * spawn of a missing Python module hits its 30s timeout and freezes the
18
+ * entire Node process (WS handshakes, tRPC subscriptions, metrics — all
19
+ * stalled). Keeping it async turns the probe into a true background task.
20
+ */
21
+ var execFileAsync$2 = (0, node_util.promisify)(node_child_process.execFile);
22
+ /** Minimal no-op logger for default parameter */
23
+ var noopLogger = {
24
+ debug() {},
25
+ info() {},
26
+ warn() {},
27
+ error() {},
28
+ child() {
29
+ return noopLogger;
30
+ },
31
+ withTags() {
32
+ return noopLogger;
33
+ }
34
+ };
35
+ /**
36
+ * Get reliable "available" RAM in MB, cross-platform.
37
+ * os.freemem() is unreliable on macOS (reports ~200MB on a 36GB system).
38
+ * Uses systeminformation when available, falls back to native commands.
39
+ */
40
+ async function getAvailableRAM_MB() {
41
+ try {
42
+ const mem = await (await import("systeminformation")).mem();
43
+ return Math.round(mem.available / 1024 / 1024);
44
+ } catch (err) {
45
+ console.debug(`systeminformation not available, using platform-specific RAM probe: ${(0, _camstack_types.errMsg)(err)}`);
46
+ const platform = node_os.platform();
47
+ try {
48
+ if (platform === "darwin") {
49
+ const { stdout: output } = await execFileAsync$2("vm_stat", [], {
50
+ encoding: "utf8",
51
+ timeout: 3e3
52
+ });
53
+ const pageSize = parseInt(output.match(/page size of (\d+)/)?.[1] ?? "16384");
54
+ const free = parseInt(output.match(/Pages free:\s+(\d+)/)?.[1] ?? "0");
55
+ const inactive = parseInt(output.match(/Pages inactive:\s+(\d+)/)?.[1] ?? "0");
56
+ const purgeable = parseInt(output.match(/Pages purgeable:\s+(\d+)/)?.[1] ?? "0");
57
+ return Math.round((free + inactive + purgeable) * pageSize / 1024 / 1024);
58
+ } else if (platform === "linux") {
59
+ const { readFileSync } = await import("node:fs");
60
+ const match = readFileSync("/proc/meminfo", "utf8").match(/MemAvailable:\s+(\d+)\s+kB/);
61
+ if (match) return Math.round(parseInt(match[1]) / 1024);
62
+ }
63
+ } catch (err) {
64
+ console.debug(`RAM probe failed, using total RAM fallback: ${(0, _camstack_types.errMsg)(err)}`);
65
+ }
66
+ return Math.round(node_os.totalmem() / 1024 / 1024);
67
+ }
68
+ }
69
+ var PlatformScorer = class {
70
+ cached = null;
71
+ logger;
72
+ /**
73
+ * Path to the embedded portable Python (from `ctx.deps.ensurePython()`).
74
+ * The Docker hub ships NO system `python3` — inference runs on the
75
+ * downloaded portable build — so probing system `python3`/`python` would
76
+ * wrongly report "Python not found" and never surface coreml/openvino
77
+ * backends. When set, the Python module probes run against THIS binary;
78
+ * `null` falls back to a system `python3`/`python` lookup (dev / agent
79
+ * environments where Python is on PATH).
80
+ */
81
+ embeddedPythonPath;
82
+ constructor(logger = noopLogger, embeddedPythonPath = null) {
83
+ this.logger = logger;
84
+ this.embeddedPythonPath = embeddedPythonPath;
85
+ }
86
+ /**
87
+ * Probe hardware + runtimes and score all backend combos.
88
+ *
89
+ * An optional `onPhase` callback is invoked at each step so consumers
90
+ * (e.g. the platform-probe addon) can emit live progress events on
91
+ * the event bus. The callback takes a phase id + a typed payload; all
92
+ * phases fire in strict order: `started` → `hardware` → `node-backends`
93
+ * → `python-backends` → `scored` → `done`. On failure, `error` fires
94
+ * once with the exception. Cached after first call.
95
+ */
96
+ async probe(onPhase) {
97
+ if (this.cached) return this.cached;
98
+ const start = Date.now();
99
+ onPhase?.("started", {});
100
+ this.logger.info("Probing hardware...");
101
+ const hardware = await this.probeHardware();
102
+ this.logger.info("Hardware detected", { meta: {
103
+ platform: hardware.platform,
104
+ arch: hardware.arch,
105
+ cpuModel: hardware.cpuModel,
106
+ cpuCores: hardware.cpuCores,
107
+ ramGB: Math.round(hardware.totalRAM_MB / 1024)
108
+ } });
109
+ if (hardware.gpu) this.logger.info("GPU detected", { meta: { name: hardware.gpu.name } });
110
+ if (hardware.npu) this.logger.info("NPU detected", { meta: { type: hardware.npu.type } });
111
+ onPhase?.("hardware", { hardware });
112
+ this.logger.info("Probing Python backends...");
113
+ const pythonInfo = await this.probePythonBackends();
114
+ if (pythonInfo.pythonPath) this.logger.info("Python backends detected", { meta: {
115
+ pythonPath: pythonInfo.pythonPath,
116
+ backends: pythonInfo.backends.filter((b) => b.available).map((b) => b.id)
117
+ } });
118
+ else this.logger.info("Python: not found");
119
+ onPhase?.("python-backends", {
120
+ pythonPath: pythonInfo.pythonPath,
121
+ backends: pythonInfo.backends
122
+ });
123
+ const scores = this.scoreBackends(hardware, pythonInfo.backends);
124
+ const bestScore = scores.find((s) => s.available) ?? scores[scores.length - 1];
125
+ const elapsed = Date.now() - start;
126
+ this.logger.info("Scoring complete", { meta: {
127
+ elapsedMs: elapsed,
128
+ combos: scores.length
129
+ } });
130
+ this.logger.info("Best backend selected", { meta: {
131
+ runtime: bestScore.runtime,
132
+ backend: bestScore.backend,
133
+ format: bestScore.format,
134
+ reason: bestScore.reason,
135
+ score: bestScore.score
136
+ } });
137
+ for (const s of scores) this.logger.debug("Score entry", { meta: {
138
+ available: s.available,
139
+ runtime: s.runtime,
140
+ backend: s.backend,
141
+ format: s.format,
142
+ score: s.score,
143
+ reason: s.reason
144
+ } });
145
+ this.cached = {
146
+ hardware,
147
+ scores,
148
+ bestScore,
149
+ pythonPath: pythonInfo.pythonPath
150
+ };
151
+ onPhase?.("scored", {
152
+ scores,
153
+ bestScore,
154
+ elapsedMs: elapsed
155
+ });
156
+ onPhase?.("done", { capabilities: this.cached });
157
+ return this.cached;
158
+ }
159
+ async probeHardware() {
160
+ const platform = node_os.platform();
161
+ const arch = node_os.arch();
162
+ const cpus = node_os.cpus();
163
+ const cpuModel = cpus[0]?.model ?? "unknown";
164
+ const cpuCores = cpus.length;
165
+ const totalRAM_MB = Math.round(node_os.totalmem() / 1024 / 1024);
166
+ const availableRAM_MB = await getAvailableRAM_MB();
167
+ this.logger.debug("RAM probed", { meta: {
168
+ totalRAM_MB,
169
+ availableRAM_MB
170
+ } });
171
+ let gpu = null;
172
+ let npu = null;
173
+ if (platform === "darwin" && arch === "arm64") {
174
+ gpu = {
175
+ type: "apple",
176
+ name: "Apple Silicon GPU"
177
+ };
178
+ npu = { type: "apple-ane" };
179
+ }
180
+ if (platform === "linux") {
181
+ try {
182
+ const { stdout } = await execFileAsync$2("nvidia-smi", ["--query-gpu=name,memory.total", "--format=csv,noheader"], {
183
+ encoding: "utf8",
184
+ timeout: 5e3
185
+ });
186
+ const output = stdout.trim();
187
+ if (output) {
188
+ const [name, mem] = output.split(",").map((s) => s.trim());
189
+ gpu = {
190
+ type: "nvidia",
191
+ name: name ?? "NVIDIA GPU",
192
+ memoryMB: parseInt(mem ?? "0")
193
+ };
194
+ }
195
+ } catch (err) {
196
+ this.logger.debug("NVIDIA GPU detection failed", { meta: { error: (0, _camstack_types.errMsg)(err) } });
197
+ }
198
+ if (!gpu || !npu) {
199
+ const { classifyIntelAccelerators } = await Promise.resolve().then(() => require("../../intel-accelerators-Gg0P5mnl.js"));
200
+ const intel = classifyIntelAccelerators({
201
+ listRenderNodes: () => {
202
+ try {
203
+ return node_fs.readdirSync("/dev/dri").filter((n) => n.startsWith("renderD")).map((n) => `/dev/dri/${n}`);
204
+ } catch {
205
+ return [];
206
+ }
207
+ },
208
+ readVendor: (node) => {
209
+ try {
210
+ return node_fs.readFileSync(`/sys/class/drm/${node.split("/").pop()}/device/vendor`, "utf8");
211
+ } catch {
212
+ return "";
213
+ }
214
+ },
215
+ exists: (p) => node_fs.existsSync(p)
216
+ });
217
+ gpu = gpu ?? intel.gpu;
218
+ npu = npu ?? intel.npu;
219
+ if (intel.npu) this.logger.info("Intel NPU detected", { meta: { device: "/dev/accel/accel0" } });
220
+ if (intel.gpu) this.logger.info("Intel iGPU detected", { meta: { name: intel.gpu.name } });
221
+ }
222
+ }
223
+ return {
224
+ platform,
225
+ arch,
226
+ cpuModel,
227
+ cpuCores,
228
+ totalRAM_MB,
229
+ availableRAM_MB,
230
+ gpu,
231
+ npu
232
+ };
233
+ }
234
+ async probePythonBackends() {
235
+ const candidates = [
236
+ ...this.embeddedPythonPath ? [this.embeddedPythonPath] : [],
237
+ "python3",
238
+ "python"
239
+ ];
240
+ let pythonPath = null;
241
+ for (const cmd of candidates) try {
242
+ await execFileAsync$2(cmd, ["--version"], { timeout: 5e3 });
243
+ pythonPath = cmd;
244
+ break;
245
+ } catch (err) {
246
+ console.debug(`Python command "${cmd}" not found: ${(0, _camstack_types.errMsg)(err)}`);
247
+ }
248
+ if (!pythonPath) return {
249
+ pythonPath: null,
250
+ backends: []
251
+ };
252
+ const results = await Promise.all([
253
+ [
254
+ "coremltools",
255
+ "coreml",
256
+ "coreml"
257
+ ],
258
+ [
259
+ "openvino.runtime",
260
+ "openvino",
261
+ "openvino"
262
+ ],
263
+ [
264
+ "torch",
265
+ "pytorch",
266
+ "onnx"
267
+ ],
268
+ [
269
+ "onnxruntime",
270
+ "onnx-py",
271
+ "onnx"
272
+ ]
273
+ ].map(async ([mod, id, format]) => {
274
+ const probeStart = Date.now();
275
+ let available = false;
276
+ try {
277
+ await execFileAsync$2(pythonPath, ["-c", `import ${mod}`], { timeout: 3e4 });
278
+ available = true;
279
+ this.logger.info("Python backend confirmed", { meta: {
280
+ backend: id,
281
+ module: mod
282
+ } });
283
+ } catch (err) {
284
+ console.debug(`Python module "${mod}" not installed: ${(0, _camstack_types.errMsg)(err)}`);
285
+ if (id === "openvino") this.logger.info("Python backend not yet confirmed: openvino (may be pending proactive install on Intel hardware — falling back to onnx-cpu)", { meta: { module: mod } });
286
+ }
287
+ const probeMs = Date.now() - probeStart;
288
+ this.logger.debug("Python module probed", { meta: {
289
+ module: mod,
290
+ available,
291
+ probeMs
292
+ } });
293
+ return {
294
+ mod,
295
+ id,
296
+ format,
297
+ available
298
+ };
299
+ }));
300
+ const backends = [];
301
+ for (const r of results) if (r.id === "coreml" && node_os.platform() === "darwin") backends.push({
302
+ id: r.id,
303
+ format: r.format,
304
+ available: r.available
305
+ });
306
+ else if (r.available) backends.push({
307
+ id: r.id,
308
+ format: r.format,
309
+ available: r.available
310
+ });
311
+ return {
312
+ pythonPath,
313
+ backends
314
+ };
315
+ }
316
+ scoreBackends(hardware, pythonBackends) {
317
+ const scores = [];
318
+ if (hardware.platform === "darwin" && hardware.arch === "arm64") {
319
+ const pyCoreMl = pythonBackends.find((b) => b.id === "coreml");
320
+ if (pyCoreMl) scores.push({
321
+ runtime: "python",
322
+ backend: "coreml",
323
+ format: "coreml",
324
+ score: 95,
325
+ reason: "Apple Neural Engine (Python CoreML)",
326
+ available: pyCoreMl.available
327
+ });
328
+ }
329
+ if (hardware.gpu?.type === "nvidia") scores.push({
330
+ runtime: "python",
331
+ backend: "cuda",
332
+ format: "onnx",
333
+ score: 85,
334
+ reason: "NVIDIA CUDA (Python ONNX Runtime)",
335
+ available: true
336
+ });
337
+ const openvino = pythonBackends.find((b) => b.id === "openvino");
338
+ if (openvino) {
339
+ const score = hardware.npu?.type === "intel-npu" ? 90 : 80;
340
+ scores.push({
341
+ runtime: "python",
342
+ backend: "openvino",
343
+ format: "openvino",
344
+ score,
345
+ reason: "Intel OpenVINO",
346
+ available: openvino.available
347
+ });
348
+ }
349
+ scores.push({
350
+ runtime: "python",
351
+ backend: "cpu",
352
+ format: "onnx",
353
+ score: 50,
354
+ reason: "CPU (Python ONNX Runtime)",
355
+ available: true
356
+ });
357
+ return scores.toSorted((a, b) => b.score - a.score);
358
+ }
359
+ };
360
+ //#endregion
361
+ //#region src/builtins/platform-probe/inference-config-resolver.ts
362
+ var InferenceConfigResolver = class {
363
+ scores;
364
+ hardware;
365
+ constructor(scores, hardware) {
366
+ this.scores = scores;
367
+ this.hardware = hardware;
368
+ }
369
+ /**
370
+ * Compute accuracy/backend weights based on available system RAM.
371
+ * availableRAM_MB is now sourced from systeminformation (reliable cross-platform),
372
+ * not os.freemem() which is broken on macOS.
373
+ *
374
+ * - > 16 GB available: prefer larger, more accurate models (accuracy 0.6, backend 0.4)
375
+ * - > 8 GB available: balanced (accuracy 0.5, backend 0.5)
376
+ * - <= 8 GB available: prefer speed (accuracy 0.4, backend 0.6)
377
+ */
378
+ getWeights() {
379
+ const ramMB = this.hardware.availableRAM_MB;
380
+ if (ramMB > 16384) return {
381
+ accuracyWeight: .6,
382
+ backendWeight: .4
383
+ };
384
+ if (ramMB > 8192) return {
385
+ accuracyWeight: .5,
386
+ backendWeight: .5
387
+ };
388
+ return {
389
+ accuracyWeight: .4,
390
+ backendWeight: .6
391
+ };
392
+ }
393
+ /**
394
+ * Given an addon's model requirements, pick the best model + runtime + backend.
395
+ *
396
+ * Algorithm:
397
+ * 1. Filter models by available RAM (minRAM_MB < 25% of available RAM)
398
+ * 2. For each remaining model, find the best platform score whose format
399
+ * is available in the model's formats
400
+ * 3. Pick the model with the highest combined score using RAM-adaptive weights:
401
+ * - High RAM (>16 GB): accuracy × 0.6 + backend × 0.4 (prefer accuracy)
402
+ * - Mid RAM (>8 GB): accuracy × 0.5 + backend × 0.5 (balanced)
403
+ * - Low RAM (<=8 GB): accuracy × 0.4 + backend × 0.6 (prefer speed)
404
+ */
405
+ resolve(requirements) {
406
+ if (requirements.length === 0) return {
407
+ modelId: "",
408
+ runtime: "node",
409
+ backend: "cpu",
410
+ format: "onnx",
411
+ reason: "No models declared"
412
+ };
413
+ const ramBudget = this.hardware.availableRAM_MB * .25;
414
+ const { accuracyWeight, backendWeight } = this.getWeights();
415
+ console.log(`[InferenceConfigResolver] availableRAM: ${this.hardware.availableRAM_MB}MB, budget: ${Math.round(ramBudget)}MB, weights: accuracy=${accuracyWeight}, backend=${backendWeight}`);
416
+ const fits = requirements.filter((m) => m.minRAM_MB < ramBudget);
417
+ const candidates = fits.length > 0 ? fits : [requirements[0]];
418
+ console.log(`[InferenceConfigResolver] ${candidates.length}/${requirements.length} models fit RAM budget`);
419
+ let bestCombo = null;
420
+ for (const model of candidates) for (const score of this.scores) {
421
+ if (!score.available) continue;
422
+ if (!model.formats.includes(score.format)) continue;
423
+ const combined = model.accuracyScore * accuracyWeight + score.score * backendWeight;
424
+ if (!bestCombo || combined > bestCombo.combined) {
425
+ console.log(`[InferenceConfigResolver] New best: ${model.modelId} (accuracy=${model.accuracyScore}) + ${score.backend}/${score.format} (score=${score.score}) → combined=${Math.round(combined)}`);
426
+ bestCombo = {
427
+ model,
428
+ score,
429
+ combined
430
+ };
431
+ }
432
+ }
433
+ if (!bestCombo) return {
434
+ modelId: candidates[0].modelId,
435
+ runtime: "node",
436
+ backend: "cpu",
437
+ format: "onnx",
438
+ reason: "No compatible backend — CPU fallback"
439
+ };
440
+ return {
441
+ modelId: bestCombo.model.modelId,
442
+ runtime: bestCombo.score.runtime,
443
+ backend: bestCombo.score.backend,
444
+ format: bestCombo.score.format,
445
+ reason: `${bestCombo.model.name} on ${bestCombo.score.reason} (score: ${Math.round(bestCombo.combined)})`
446
+ };
447
+ }
448
+ };
449
+ //#endregion
450
+ //#region src/builtins/platform-probe/hardware-encoder-probe.ts
451
+ var execFileAsync$1 = (0, node_util.promisify)(node_child_process.execFile);
452
+ function buildCandidates(hardware) {
453
+ const out = [];
454
+ if (hardware.platform === "darwin") {
455
+ out.push({
456
+ encoder: "h264_videotoolbox",
457
+ codec: "H264",
458
+ family: "videotoolbox"
459
+ });
460
+ out.push({
461
+ encoder: "hevc_videotoolbox",
462
+ codec: "H265",
463
+ family: "videotoolbox"
464
+ });
465
+ }
466
+ if (hardware.platform === "linux") {
467
+ if (hardware.gpu?.type === "nvidia") {
468
+ out.push({
469
+ encoder: "h264_nvenc",
470
+ codec: "H264",
471
+ family: "nvenc"
472
+ });
473
+ out.push({
474
+ encoder: "hevc_nvenc",
475
+ codec: "H265",
476
+ family: "nvenc"
477
+ });
478
+ }
479
+ if (hardware.gpu?.type === "intel" || hardware.gpu?.type === "amd" || !hardware.gpu) {
480
+ out.push({
481
+ encoder: "h264_vaapi",
482
+ codec: "H264",
483
+ family: "vaapi"
484
+ });
485
+ out.push({
486
+ encoder: "hevc_vaapi",
487
+ codec: "H265",
488
+ family: "vaapi"
489
+ });
490
+ }
491
+ }
492
+ return out;
493
+ }
494
+ async function runTestEncode(candidate, opts) {
495
+ const ffmpeg = opts.ffmpegPath ?? "ffmpeg";
496
+ const timeout = opts.timeoutMs ?? 8e3;
497
+ const nullSink = node_os.platform() === "win32" ? "NUL" : "/dev/null";
498
+ const baseArgs = [
499
+ "-hide_banner",
500
+ "-loglevel",
501
+ "error"
502
+ ];
503
+ const inArgs = [
504
+ "-f",
505
+ "lavfi",
506
+ "-i",
507
+ "testsrc=duration=0.04:size=16x16:rate=25"
508
+ ];
509
+ let outArgs;
510
+ if (candidate.family === "vaapi") outArgs = [
511
+ "-vaapi_device",
512
+ "/dev/dri/renderD128",
513
+ "-vf",
514
+ "format=nv12,hwupload",
515
+ "-c:v",
516
+ candidate.encoder,
517
+ "-frames:v",
518
+ "1",
519
+ "-f",
520
+ "null",
521
+ nullSink
522
+ ];
523
+ else outArgs = [
524
+ "-c:v",
525
+ candidate.encoder,
526
+ "-frames:v",
527
+ "1",
528
+ "-f",
529
+ "null",
530
+ nullSink
531
+ ];
532
+ try {
533
+ await execFileAsync$1(ffmpeg, [
534
+ ...baseArgs,
535
+ ...inArgs,
536
+ ...outArgs
537
+ ], {
538
+ timeout,
539
+ encoding: "utf8"
540
+ });
541
+ return {
542
+ encoder: candidate.encoder,
543
+ codec: candidate.codec,
544
+ family: candidate.family,
545
+ available: true
546
+ };
547
+ } catch (err) {
548
+ return {
549
+ encoder: candidate.encoder,
550
+ codec: candidate.codec,
551
+ family: candidate.family,
552
+ available: false,
553
+ reason: (0, _camstack_types.errMsg)(err)
554
+ };
555
+ }
556
+ }
557
+ var HardwareEncoderProber = class {
558
+ cached = null;
559
+ inflight = null;
560
+ logger;
561
+ ffmpegPath;
562
+ constructor(logger, ffmpegPath = "ffmpeg") {
563
+ this.logger = logger;
564
+ this.ffmpegPath = ffmpegPath;
565
+ }
566
+ getCached() {
567
+ return this.cached;
568
+ }
569
+ async probe(hardware, options = {}) {
570
+ if (!options.force && this.cached) return this.cached;
571
+ if (this.inflight) return this.inflight;
572
+ this.inflight = this.runProbe(hardware).then((res) => {
573
+ this.cached = res;
574
+ this.inflight = null;
575
+ return res;
576
+ }).catch((err) => {
577
+ this.inflight = null;
578
+ throw err;
579
+ });
580
+ return this.inflight;
581
+ }
582
+ async runProbe(hardware) {
583
+ const candidates = buildCandidates(hardware);
584
+ const start = Date.now();
585
+ this.logger.info("Probing hardware encoders", { meta: {
586
+ platform: hardware.platform,
587
+ arch: hardware.arch,
588
+ candidates: candidates.length
589
+ } });
590
+ const probes = await Promise.all(candidates.map((c) => runTestEncode(c, { ffmpegPath: this.ffmpegPath })));
591
+ probes.push({
592
+ encoder: "libx264",
593
+ codec: "H264",
594
+ family: "software",
595
+ available: true
596
+ });
597
+ probes.push({
598
+ encoder: "libx265",
599
+ codec: "H265",
600
+ family: "software",
601
+ available: true
602
+ });
603
+ const pickDefault = (codec) => {
604
+ const hw = probes.find((p) => p.codec === codec && p.available && p.family !== "software");
605
+ if (hw) return hw.encoder;
606
+ return codec === "H264" ? "libx264" : "libx265";
607
+ };
608
+ const result = {
609
+ encoders: probes,
610
+ defaultH264: pickDefault("H264"),
611
+ defaultH265: pickDefault("H265"),
612
+ probedAt: Date.now()
613
+ };
614
+ const elapsed = Date.now() - start;
615
+ this.logger.info("Hardware encoder probe complete", { meta: {
616
+ elapsedMs: elapsed,
617
+ defaultH264: result.defaultH264,
618
+ defaultH265: result.defaultH265,
619
+ availableHw: probes.filter((p) => p.available && p.family !== "software").map((p) => p.encoder)
620
+ } });
621
+ return result;
622
+ }
623
+ };
624
+ //#endregion
625
+ //#region src/builtins/platform-probe/hardware-decode-accel-probe.ts
626
+ var execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
627
+ var defaultExecFn = async (ffmpegPath, args) => {
628
+ const { stdout } = await execFileAsync(ffmpegPath, [...args], {
629
+ timeout: 8e3,
630
+ encoding: "utf8"
631
+ });
632
+ return { stdout };
633
+ };
634
+ /**
635
+ * Parse the output of `ffmpeg -hwaccels`. The listing looks like:
636
+ *
637
+ * Hardware acceleration methods:
638
+ * videotoolbox
639
+ *
640
+ * The header line is dropped; remaining non-empty trimmed lines are the
641
+ * method names, lowercased and de-duplicated (order preserved).
642
+ */
643
+ function parseHwAccelsOutput(stdout) {
644
+ const seen = /* @__PURE__ */ new Set();
645
+ const methods = [];
646
+ for (const raw of stdout.split("\n")) {
647
+ const line = raw.trim().toLowerCase();
648
+ if (line.length === 0) continue;
649
+ if (line.endsWith("methods:")) continue;
650
+ if (seen.has(line)) continue;
651
+ seen.add(line);
652
+ methods.push(line);
653
+ }
654
+ return methods;
655
+ }
656
+ /**
657
+ * Probes which `-hwaccel` decode backends the configured ffmpeg binary
658
+ * supports. Mirrors {@link HardwareEncoderProber} (configured binary, cached,
659
+ * single-flight, forceable). Never throws: a probe failure yields an empty
660
+ * method list so callers fall back to software decode.
661
+ */
662
+ var HardwareDecodeAccelProber = class {
663
+ cached = null;
664
+ inflight = null;
665
+ logger;
666
+ ffmpegPath;
667
+ execFn;
668
+ constructor(logger, ffmpegPath = "ffmpeg", execFn = defaultExecFn) {
669
+ this.logger = logger;
670
+ this.ffmpegPath = ffmpegPath;
671
+ this.execFn = execFn;
672
+ }
673
+ getCached() {
674
+ return this.cached;
675
+ }
676
+ async probe(options = {}) {
677
+ if (!options.force && this.cached) return this.cached;
678
+ if (this.inflight) return this.inflight;
679
+ this.inflight = this.runProbe().then((res) => {
680
+ this.cached = res;
681
+ this.inflight = null;
682
+ return res;
683
+ }).catch((err) => {
684
+ this.inflight = null;
685
+ throw err;
686
+ });
687
+ return this.inflight;
688
+ }
689
+ async runProbe() {
690
+ try {
691
+ const { stdout } = await this.execFn(this.ffmpegPath, ["-hide_banner", "-hwaccels"]);
692
+ const methods = parseHwAccelsOutput(stdout);
693
+ this.logger.info("Hardware decode-accel probe complete", { meta: { methods } });
694
+ return {
695
+ methods,
696
+ probedAt: Date.now()
697
+ };
698
+ } catch (err) {
699
+ this.logger.warn("Hardware decode-accel probe failed — assuming none available", { meta: { error: (0, _camstack_types.errMsg)(err) } });
700
+ return {
701
+ methods: [],
702
+ probedAt: Date.now()
703
+ };
704
+ }
705
+ }
706
+ };
707
+ //#endregion
708
+ //#region src/builtins/platform-probe/index.ts
709
+ var PlatformProbeNativeAddon = class extends _camstack_types.BaseAddon {
710
+ scorer = null;
711
+ encoderProber = null;
712
+ decodeAccelProber = null;
713
+ cachedCaps = null;
714
+ constructor() {
715
+ super({});
716
+ }
717
+ /**
718
+ * Resolve the ffmpeg binary the encoder probe should test, from the cluster
719
+ * `ffmpeg` config section (`binaryPath`). The probe MUST exercise the same
720
+ * binary the broker/recorder spawn, or it may report encoders for a different
721
+ * ffmpeg. Defaults to PATH `ffmpeg` on any miss.
722
+ */
723
+ async resolveFfmpegBinaryPath() {
724
+ try {
725
+ const bp = (await this.ctx.settings?.getSection("ffmpeg") ?? {})["binaryPath"];
726
+ return typeof bp === "string" && bp.trim().length > 0 ? bp : "ffmpeg";
727
+ } catch {
728
+ return "ffmpeg";
729
+ }
730
+ }
731
+ async onInitialize() {
732
+ const embeddedPython = await this.ctx.deps.ensurePython().catch((err) => {
733
+ this.ctx.logger.debug("ensurePython unavailable for platform probe", { meta: { error: (0, _camstack_types.errMsg)(err) } });
734
+ return null;
735
+ });
736
+ this.scorer = new PlatformScorer(this.ctx.logger, embeddedPython);
737
+ const ffmpegPath = await this.resolveFfmpegBinaryPath();
738
+ this.encoderProber = new HardwareEncoderProber(this.ctx.logger, ffmpegPath);
739
+ this.decodeAccelProber = new HardwareDecodeAccelProber(this.ctx.logger, ffmpegPath);
740
+ const emitPhase = (phase, payload) => {
741
+ this.ctx.eventBus?.emit({
742
+ id: `platform-probe-${phase}-${Date.now()}`,
743
+ timestamp: /* @__PURE__ */ new Date(),
744
+ source: {
745
+ type: "core",
746
+ id: "platform-probe-native"
747
+ },
748
+ category: _camstack_types.EventCategory.PlatformProbePhase,
749
+ data: {
750
+ type: "platform-probe.phase",
751
+ phase,
752
+ ...payload
753
+ }
754
+ });
755
+ };
756
+ const probePromise = this.scorer.probe(emitPhase).then((caps) => {
757
+ this.cachedCaps = caps;
758
+ this.ctx.logger.info("Platform probe complete", { meta: {
759
+ cpuModel: caps.hardware.cpuModel,
760
+ arch: caps.hardware.arch,
761
+ totalRAM_MB: caps.hardware.totalRAM_MB,
762
+ gpu: caps.hardware.gpu?.name ?? "none",
763
+ bestReason: caps.bestScore.reason,
764
+ bestScore: caps.bestScore.score
765
+ } });
766
+ return caps;
767
+ }).catch((err) => {
768
+ const msg = (0, _camstack_types.errMsg)(err);
769
+ this.ctx.logger.error("Platform probe failed", { meta: { error: msg } });
770
+ emitPhase("error", { message: msg });
771
+ throw err;
772
+ });
773
+ const getCaps = async () => {
774
+ return this.cachedCaps ?? probePromise;
775
+ };
776
+ return [{
777
+ capability: _camstack_types.platformProbeCapability,
778
+ provider: {
779
+ getCapabilities: async () => {
780
+ return getCaps();
781
+ },
782
+ getHardware: async () => {
783
+ return (await getCaps()).hardware;
784
+ },
785
+ resolveInferenceConfig: async (input) => {
786
+ const caps = await getCaps();
787
+ return new InferenceConfigResolver(caps.scores, caps.hardware).resolve(input.requirements);
788
+ },
789
+ resolveHwAccel: async (input) => {
790
+ const hwaccel = this.ctx.kernel.hwaccel;
791
+ if (!hwaccel) return { preferred: [] };
792
+ return { preferred: (await hwaccel.resolve(input.prefer ?? null)).preferred };
793
+ },
794
+ getHardwareEncoders: async () => {
795
+ const prober = this.encoderProber;
796
+ if (!prober) throw new Error("Hardware encoder prober not initialized");
797
+ const cached = prober.getCached();
798
+ if (cached) return cached;
799
+ const caps = await getCaps();
800
+ return prober.probe(caps.hardware);
801
+ },
802
+ refreshHardwareEncoders: async () => {
803
+ const prober = this.encoderProber;
804
+ if (!prober) throw new Error("Hardware encoder prober not initialized");
805
+ const caps = await getCaps();
806
+ return prober.probe(caps.hardware, { force: true });
807
+ },
808
+ getHardwareDecodeAccels: async () => {
809
+ const prober = this.decodeAccelProber;
810
+ if (!prober) throw new Error("Hardware decode-accel prober not initialized");
811
+ return prober.probe();
812
+ },
813
+ refreshHardwareDecodeAccels: async () => {
814
+ const prober = this.decodeAccelProber;
815
+ if (!prober) throw new Error("Hardware decode-accel prober not initialized");
816
+ return prober.probe({ force: true });
817
+ }
818
+ }
819
+ }];
820
+ }
821
+ async onShutdown() {
822
+ this.scorer = null;
823
+ this.encoderProber = null;
824
+ this.decodeAccelProber = null;
825
+ this.cachedCaps = null;
826
+ }
827
+ };
828
+ //#endregion
829
+ exports.HardwareDecodeAccelProber = HardwareDecodeAccelProber;
830
+ exports.HardwareEncoderProber = HardwareEncoderProber;
831
+ exports.InferenceConfigResolver = InferenceConfigResolver;
832
+ exports.PlatformProbeNativeAddon = PlatformProbeNativeAddon;
833
+ exports.default = PlatformProbeNativeAddon;
834
+ exports.PlatformScorer = PlatformScorer;