@infersec/conduit 1.36.0 → 1.38.0

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.
package/dist/cli.js CHANGED
@@ -6,7 +6,7 @@ const __dirname = __pathDirname(__filename);
6
6
 
7
7
  import { parseArgs } from 'node:util';
8
8
  import 'node:crypto';
9
- import { a as asError, s as startInferenceAgent } from './start-CdILFvRO.js';
9
+ import { a as asError, s as startInferenceAgent } from './start-BvzHFdA_.js';
10
10
  import 'argon2';
11
11
  import 'node:child_process';
12
12
  import 'node:stream';
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ const __filename = __fileURLToPath(import.meta.url);
5
5
  const __dirname = __pathDirname(__filename);
6
6
 
7
7
  import 'node:crypto';
8
- import { s as startInferenceAgent, a as asError } from './start-CdILFvRO.js';
8
+ import { s as startInferenceAgent, a as asError } from './start-BvzHFdA_.js';
9
9
  import 'argon2';
10
10
  import 'node:child_process';
11
11
  import 'node:stream';
@@ -119700,11 +119700,28 @@ createExeca(mapScriptAsync, {}, deepScriptOptions, setScriptSync);
119700
119700
 
119701
119701
  getIpcExport();
119702
119702
 
119703
+ const DRM_PATH = "/sys/class/drm";
119704
+ const GPU_PCI_CLASS_RE = /\[(03\d\d)\]/;
119703
119705
  const MACHINE_ID_PATHS = ["/etc/machine-id", "/var/lib/dbus/machine-id"];
119706
+ function stripQuotes(value) {
119707
+ return value.replace(/^"|"$/g, "");
119708
+ }
119709
+ function extractHumanPart(value) {
119710
+ return value.replace(/\s*\[[^\]]*\]\s*$/, "").trim();
119711
+ }
119712
+ async function readSysfsFile(filePath) {
119713
+ try {
119714
+ const contents = await readFile(filePath, "utf8");
119715
+ return contents.trim();
119716
+ }
119717
+ catch {
119718
+ return null;
119719
+ }
119720
+ }
119704
119721
  async function readMachineIdentifier() {
119705
- for (const path of MACHINE_ID_PATHS) {
119722
+ for (const targetPath of MACHINE_ID_PATHS) {
119706
119723
  try {
119707
- const contents = await readFile(path, "utf8");
119724
+ const contents = await readFile(targetPath, "utf8");
119708
119725
  const trimmed = contents.trim();
119709
119726
  if (trimmed.length > 0) {
119710
119727
  return trimmed;
@@ -119745,6 +119762,11 @@ function normalizeMegabytes(value) {
119745
119762
  }
119746
119763
  return Math.round(value * 1024 * 1024);
119747
119764
  }
119765
+ function normalizeBusAddress(bus) {
119766
+ if (!bus)
119767
+ return null;
119768
+ return bus.toLowerCase().replace(/^0000:/, "");
119769
+ }
119748
119770
  function resolveCpuValue(value) {
119749
119771
  if (typeof value === "number" && Number.isFinite(value)) {
119750
119772
  return value;
@@ -119755,12 +119777,199 @@ function resolveCpuValue(value) {
119755
119777
  }
119756
119778
  return null;
119757
119779
  }
119780
+ async function detectGPUsViaLspci() {
119781
+ try {
119782
+ const { stdout } = await execa("lspci", ["-nn", "-mm", "-D"]);
119783
+ const lines = stdout.split("\n");
119784
+ const gpus = [];
119785
+ for (const line of lines) {
119786
+ const fields = line.split("\t");
119787
+ if (fields.length < 4)
119788
+ continue;
119789
+ const classField = stripQuotes(fields[1] ?? "");
119790
+ const classMatch = classField.match(GPU_PCI_CLASS_RE);
119791
+ if (!classMatch)
119792
+ continue;
119793
+ const bus = stripQuotes(fields[0] ?? "");
119794
+ const vendor = extractHumanPart(stripQuotes(fields[2] ?? ""));
119795
+ const model = extractHumanPart(stripQuotes(fields[3] ?? ""));
119796
+ if (bus && model) {
119797
+ gpus.push({ bus, model, vendor });
119798
+ }
119799
+ }
119800
+ return gpus;
119801
+ }
119802
+ catch {
119803
+ return [];
119804
+ }
119805
+ }
119806
+ async function resolveDrmCardBus(cardName) {
119807
+ const deviceLink = path$1.join(DRM_PATH, cardName, "device");
119808
+ try {
119809
+ const { readlink } = await import('node:fs/promises');
119810
+ const linkTarget = await readlink(deviceLink);
119811
+ const basename = path$1.basename(linkTarget);
119812
+ if (/^[0-9a-f]{4}:[0-9a-f]{2}:[0-9a-f]{2}\.\d$/i.test(basename)) {
119813
+ return basename;
119814
+ }
119815
+ }
119816
+ catch {
119817
+ // Not a PCI device or readlink unavailable
119818
+ }
119819
+ return null;
119820
+ }
119821
+ async function enumerateDrmCards() {
119822
+ try {
119823
+ const entries = await readdir(DRM_PATH);
119824
+ const buses = [];
119825
+ for (const entry of entries) {
119826
+ if (!entry.startsWith("card") || entry.includes("-"))
119827
+ continue;
119828
+ const bus = await resolveDrmCardBus(entry);
119829
+ if (bus)
119830
+ buses.push(bus);
119831
+ }
119832
+ return buses;
119833
+ }
119834
+ catch {
119835
+ return [];
119836
+ }
119837
+ }
119838
+ async function detectVRAMViaSysfs(pciBusSuffix) {
119839
+ try {
119840
+ const entries = await readdir(DRM_PATH);
119841
+ for (const entry of entries) {
119842
+ if (!entry.startsWith("card") || entry.includes("-"))
119843
+ continue;
119844
+ const cardBus = await resolveDrmCardBus(entry);
119845
+ if (!cardBus)
119846
+ continue;
119847
+ const normalizedCard = normalizeBusAddress(cardBus);
119848
+ const normalizedTarget = normalizeBusAddress(pciBusSuffix);
119849
+ if (normalizedCard !== normalizedTarget)
119850
+ continue;
119851
+ const deviceDir = path$1.join(DRM_PATH, entry, "device");
119852
+ const totalStr = await readSysfsFile(path$1.join(deviceDir, "mem_info_vram_total"));
119853
+ const usedStr = await readSysfsFile(path$1.join(deviceDir, "mem_info_vram_used"));
119854
+ const totalBytes = totalStr !== null ? parseInt(totalStr, 10) : null;
119855
+ const usedBytes = usedStr !== null ? parseInt(usedStr, 10) : null;
119856
+ const validTotal = totalBytes !== null && Number.isFinite(totalBytes) && totalBytes >= 0;
119857
+ const validUsed = usedBytes !== null && Number.isFinite(usedBytes) && usedBytes >= 0;
119858
+ if (validTotal) {
119859
+ return {
119860
+ memoryTotalBytes: totalBytes,
119861
+ memoryUsedBytes: validUsed ? usedBytes : null
119862
+ };
119863
+ }
119864
+ }
119865
+ }
119866
+ catch {
119867
+ // sysfs not available
119868
+ }
119869
+ return { memoryTotalBytes: null, memoryUsedBytes: null };
119870
+ }
119871
+ async function detectVRAMViaRocmSmi() {
119872
+ try {
119873
+ const { stdout } = await execa("rocm-smi", [
119874
+ "--showbus",
119875
+ "--showmeminfo",
119876
+ "vram",
119877
+ "--json"
119878
+ ]);
119879
+ const parsed = JSON.parse(stdout);
119880
+ const results = [];
119881
+ const cards = Object.entries(parsed).filter(([key]) => key.startsWith("card"));
119882
+ for (const [, data] of cards) {
119883
+ const bus = data["PCI Bus"] ?? null;
119884
+ const totalStr = data["VRAM Total Memory (B)"] ?? null;
119885
+ const usedStr = data["VRAM Total Used Memory (B)"] ?? null;
119886
+ const totalBytes = totalStr !== null ? parseInt(totalStr, 10) : null;
119887
+ const usedBytes = usedStr !== null ? parseInt(usedStr, 10) : null;
119888
+ const validTotal = totalBytes !== null && Number.isFinite(totalBytes) && totalBytes >= 0;
119889
+ const validUsed = usedBytes !== null && Number.isFinite(usedBytes) && usedBytes >= 0;
119890
+ if (bus) {
119891
+ results.push({
119892
+ bus,
119893
+ memoryTotalBytes: validTotal ? totalBytes : null,
119894
+ memoryUsedBytes: validUsed ? usedBytes : null
119895
+ });
119896
+ }
119897
+ }
119898
+ return results;
119899
+ }
119900
+ catch {
119901
+ return [];
119902
+ }
119903
+ }
119904
+ function buildMergedGPUs(options) {
119905
+ const { lspciGPUs, rocmVRAM, siGPUs, sysfsVRAMMap } = options;
119906
+ const siByBus = new Map();
119907
+ for (const gpu of siGPUs) {
119908
+ const key = normalizeBusAddress(gpu.bus);
119909
+ if (key)
119910
+ siByBus.set(key, gpu);
119911
+ }
119912
+ const rocmByBus = new Map();
119913
+ for (const entry of rocmVRAM) {
119914
+ const key = normalizeBusAddress(entry.bus);
119915
+ if (key)
119916
+ rocmByBus.set(key, entry);
119917
+ }
119918
+ const seen = new Set();
119919
+ const merged = [...siGPUs];
119920
+ for (const lspciGPU of lspciGPUs) {
119921
+ const key = normalizeBusAddress(lspciGPU.bus);
119922
+ if (!key || seen.has(key))
119923
+ continue;
119924
+ seen.add(key);
119925
+ const existing = siByBus.get(key);
119926
+ if (existing) {
119927
+ if (existing.memoryTotalBytes === null) {
119928
+ const sysfs = sysfsVRAMMap.get(key);
119929
+ const sysfsTotal = sysfs?.memoryTotalBytes ?? null;
119930
+ const sysfsUsed = sysfs?.memoryUsedBytes ?? null;
119931
+ const validSysfsTotal = sysfsTotal !== null && Number.isFinite(sysfsTotal);
119932
+ const validSysfsUsed = sysfsUsed !== null && Number.isFinite(sysfsUsed);
119933
+ if (validSysfsTotal) {
119934
+ existing.memoryTotalBytes = sysfsTotal;
119935
+ existing.memoryFreeBytes =
119936
+ validSysfsUsed && sysfsUsed !== null ? sysfsTotal - sysfsUsed : null;
119937
+ }
119938
+ }
119939
+ continue;
119940
+ }
119941
+ const sysfs = sysfsVRAMMap.get(key);
119942
+ let totalBytes = sysfs?.memoryTotalBytes ?? null;
119943
+ let usedBytes = sysfs?.memoryUsedBytes ?? null;
119944
+ if (totalBytes === null) {
119945
+ const rocm = rocmByBus.get(key);
119946
+ if (rocm) {
119947
+ totalBytes = rocm.memoryTotalBytes;
119948
+ usedBytes = rocm.memoryUsedBytes;
119949
+ }
119950
+ }
119951
+ merged.push({
119952
+ bus: lspciGPU.bus,
119953
+ driverVersion: null,
119954
+ memoryFreeBytes: totalBytes !== null && usedBytes !== null && Number.isFinite(usedBytes)
119955
+ ? totalBytes - usedBytes
119956
+ : null,
119957
+ memoryTotalBytes: totalBytes,
119958
+ model: lspciGPU.model,
119959
+ temperatureCelsius: null,
119960
+ vendor: lspciGPU.vendor
119961
+ });
119962
+ }
119963
+ return merged;
119964
+ }
119758
119965
  async function collectMachineMetadata() {
119759
- const [cpuResult, memResult, osResult, graphicsResult] = await Promise.allSettled([
119966
+ const [cpuResult, memResult, osResult, graphicsResult, lspciGPUs, rocmVRAM] = await Promise.allSettled([
119760
119967
  si.cpu(),
119761
119968
  si.mem(),
119762
119969
  si.osInfo(),
119763
- si.graphics()
119970
+ si.graphics(),
119971
+ detectGPUsViaLspci(),
119972
+ detectVRAMViaRocmSmi()
119764
119973
  ]);
119765
119974
  const cpuInfo = cpuResult.status === "fulfilled" ? cpuResult.value : null;
119766
119975
  const memInfo = memResult.status === "fulfilled" ? memResult.value : null;
@@ -119768,7 +119977,9 @@ async function collectMachineMetadata() {
119768
119977
  const graphicsInfo = graphicsResult.status === "fulfilled"
119769
119978
  ? graphicsResult.value
119770
119979
  : { controllers: [] };
119771
- const gpus = (graphicsInfo.controllers ?? []).map((controller) => ({
119980
+ const resolvedLspciGPUs = lspciGPUs.status === "fulfilled" ? lspciGPUs.value : [];
119981
+ const resolvedRocmVRAM = rocmVRAM.status === "fulfilled" ? rocmVRAM.value : [];
119982
+ const siGPUs = (graphicsInfo.controllers ?? []).map((controller) => ({
119772
119983
  bus: controller.bus ?? null,
119773
119984
  driverVersion: controller.driverVersion ?? null,
119774
119985
  memoryFreeBytes: normalizeMegabytes(controller.memoryFree ?? null),
@@ -119777,6 +119988,32 @@ async function collectMachineMetadata() {
119777
119988
  temperatureCelsius: controller.temperatureGpu ?? null,
119778
119989
  vendor: controller.vendor ?? null
119779
119990
  }));
119991
+ const busSources = new Set();
119992
+ for (const lspciGPU of resolvedLspciGPUs) {
119993
+ busSources.add(lspciGPU.bus);
119994
+ }
119995
+ for (const siGPU of siGPUs) {
119996
+ if (siGPU.bus)
119997
+ busSources.add(siGPU.bus);
119998
+ }
119999
+ const drmBuses = await enumerateDrmCards();
120000
+ for (const bus of drmBuses) {
120001
+ busSources.add(bus);
120002
+ }
120003
+ const sysfsVRAMMap = new Map();
120004
+ for (const bus of busSources) {
120005
+ const busSuffix = bus.replace(/^0000:/, "");
120006
+ const vram = await detectVRAMViaSysfs(busSuffix);
120007
+ const key = normalizeBusAddress(bus);
120008
+ if (key)
120009
+ sysfsVRAMMap.set(key, vram);
120010
+ }
120011
+ const gpus = buildMergedGPUs({
120012
+ lspciGPUs: resolvedLspciGPUs,
120013
+ rocmVRAM: resolvedRocmVRAM,
120014
+ siGPUs,
120015
+ sysfsVRAMMap
120016
+ });
119780
120017
  const machineMetadata = {
119781
120018
  cpu: {
119782
120019
  baseClockGHz: resolveCpuValue(cpuInfo?.speed ?? null),
@@ -1,2 +1,2 @@
1
- import { InferenceAgentMachineMetadata } from "@infersec/definitions";
1
+ import type { InferenceAgentMachineMetadata } from "@infersec/definitions";
2
2
  export declare function collectMachineMetadata(): Promise<InferenceAgentMachineMetadata>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@infersec/conduit",
3
3
  "description": "End user conduit agent for connecting local LLMs to the cloud.",
4
- "version": "1.36.0",
4
+ "version": "1.38.0",
5
5
  "bin": {
6
6
  "infersec-conduit": "./dist/cli.js"
7
7
  },