@camstack/types 1.1.22 → 1.1.24

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.
@@ -148,6 +148,7 @@ declare const AgentLoadSummarySchema: z.ZodObject<{
148
148
  }, z.core.$strip>;
149
149
  }, z.core.$strip>;
150
150
  score: z.ZodNumber;
151
+ decodeHwaccel: z.ZodNullable<z.ZodString>;
151
152
  }, z.core.$strip>;
152
153
  /**
153
154
  * Aggregate metrics across the whole detection cluster. Replaces the legacy
@@ -543,6 +544,7 @@ export declare const pipelineOrchestratorCapability: {
543
544
  }, z.core.$strip>;
544
545
  }, z.core.$strip>;
545
546
  score: z.ZodNumber;
547
+ decodeHwaccel: z.ZodNullable<z.ZodString>;
546
548
  }, z.core.$strip>>>, import("./capability-definition.js").CapabilityMethodKind>;
547
549
  /** Aggregate global metrics across the whole detection cluster. */
548
550
  readonly getGlobalMetrics: import("./capability-definition.js").CapabilityMethodSchema<z.ZodVoid, z.ZodObject<{
@@ -268,143 +268,6 @@ export declare const platformProbeCapability: {
268
268
  preferred: z.ZodReadonly<z.ZodArray<z.ZodString>>;
269
269
  rationale: z.ZodString;
270
270
  }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
271
- /**
272
- * Hardware-encoder probe — see Task #185. Cached after first call.
273
- */
274
- readonly getHardwareEncoders: import("./capability-definition.js").CapabilityMethodSchema<z.ZodVoid, z.ZodObject<{
275
- encoders: z.ZodReadonly<z.ZodArray<z.ZodObject<{
276
- encoder: z.ZodEnum<{
277
- h264_videotoolbox: "h264_videotoolbox";
278
- hevc_videotoolbox: "hevc_videotoolbox";
279
- h264_vaapi: "h264_vaapi";
280
- hevc_vaapi: "hevc_vaapi";
281
- h264_nvenc: "h264_nvenc";
282
- hevc_nvenc: "hevc_nvenc";
283
- h264_qsv: "h264_qsv";
284
- hevc_qsv: "hevc_qsv";
285
- h264_amf: "h264_amf";
286
- hevc_amf: "hevc_amf";
287
- libx264: "libx264";
288
- libx265: "libx265";
289
- }>;
290
- codec: z.ZodEnum<{
291
- H264: "H264";
292
- H265: "H265";
293
- }>;
294
- family: z.ZodEnum<{
295
- videotoolbox: "videotoolbox";
296
- vaapi: "vaapi";
297
- qsv: "qsv";
298
- amf: "amf";
299
- nvenc: "nvenc";
300
- software: "software";
301
- }>;
302
- available: z.ZodBoolean;
303
- reason: z.ZodOptional<z.ZodString>;
304
- }, z.core.$strip>>>;
305
- defaultH264: z.ZodEnum<{
306
- h264_videotoolbox: "h264_videotoolbox";
307
- hevc_videotoolbox: "hevc_videotoolbox";
308
- h264_vaapi: "h264_vaapi";
309
- hevc_vaapi: "hevc_vaapi";
310
- h264_nvenc: "h264_nvenc";
311
- hevc_nvenc: "hevc_nvenc";
312
- h264_qsv: "h264_qsv";
313
- hevc_qsv: "hevc_qsv";
314
- h264_amf: "h264_amf";
315
- hevc_amf: "hevc_amf";
316
- libx264: "libx264";
317
- libx265: "libx265";
318
- }>;
319
- defaultH265: z.ZodEnum<{
320
- h264_videotoolbox: "h264_videotoolbox";
321
- hevc_videotoolbox: "hevc_videotoolbox";
322
- h264_vaapi: "h264_vaapi";
323
- hevc_vaapi: "hevc_vaapi";
324
- h264_nvenc: "h264_nvenc";
325
- hevc_nvenc: "hevc_nvenc";
326
- h264_qsv: "h264_qsv";
327
- hevc_qsv: "hevc_qsv";
328
- h264_amf: "h264_amf";
329
- hevc_amf: "hevc_amf";
330
- libx264: "libx264";
331
- libx265: "libx265";
332
- }>;
333
- probedAt: z.ZodNumber;
334
- }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
335
- readonly refreshHardwareEncoders: import("./capability-definition.js").CapabilityMethodSchema<z.ZodVoid, z.ZodObject<{
336
- encoders: z.ZodReadonly<z.ZodArray<z.ZodObject<{
337
- encoder: z.ZodEnum<{
338
- h264_videotoolbox: "h264_videotoolbox";
339
- hevc_videotoolbox: "hevc_videotoolbox";
340
- h264_vaapi: "h264_vaapi";
341
- hevc_vaapi: "hevc_vaapi";
342
- h264_nvenc: "h264_nvenc";
343
- hevc_nvenc: "hevc_nvenc";
344
- h264_qsv: "h264_qsv";
345
- hevc_qsv: "hevc_qsv";
346
- h264_amf: "h264_amf";
347
- hevc_amf: "hevc_amf";
348
- libx264: "libx264";
349
- libx265: "libx265";
350
- }>;
351
- codec: z.ZodEnum<{
352
- H264: "H264";
353
- H265: "H265";
354
- }>;
355
- family: z.ZodEnum<{
356
- videotoolbox: "videotoolbox";
357
- vaapi: "vaapi";
358
- qsv: "qsv";
359
- amf: "amf";
360
- nvenc: "nvenc";
361
- software: "software";
362
- }>;
363
- available: z.ZodBoolean;
364
- reason: z.ZodOptional<z.ZodString>;
365
- }, z.core.$strip>>>;
366
- defaultH264: z.ZodEnum<{
367
- h264_videotoolbox: "h264_videotoolbox";
368
- hevc_videotoolbox: "hevc_videotoolbox";
369
- h264_vaapi: "h264_vaapi";
370
- hevc_vaapi: "hevc_vaapi";
371
- h264_nvenc: "h264_nvenc";
372
- hevc_nvenc: "hevc_nvenc";
373
- h264_qsv: "h264_qsv";
374
- hevc_qsv: "hevc_qsv";
375
- h264_amf: "h264_amf";
376
- hevc_amf: "hevc_amf";
377
- libx264: "libx264";
378
- libx265: "libx265";
379
- }>;
380
- defaultH265: z.ZodEnum<{
381
- h264_videotoolbox: "h264_videotoolbox";
382
- hevc_videotoolbox: "hevc_videotoolbox";
383
- h264_vaapi: "h264_vaapi";
384
- hevc_vaapi: "hevc_vaapi";
385
- h264_nvenc: "h264_nvenc";
386
- hevc_nvenc: "hevc_nvenc";
387
- h264_qsv: "h264_qsv";
388
- hevc_qsv: "hevc_qsv";
389
- h264_amf: "h264_amf";
390
- hevc_amf: "hevc_amf";
391
- libx264: "libx264";
392
- libx265: "libx265";
393
- }>;
394
- probedAt: z.ZodNumber;
395
- }, z.core.$strip>, "mutation">;
396
- /**
397
- * Decode-side hw-accel probe — the `-hwaccel` methods the configured ffmpeg
398
- * binary supports (via `ffmpeg -hwaccels`). Cached after first call.
399
- */
400
- readonly getHardwareDecodeAccels: import("./capability-definition.js").CapabilityMethodSchema<z.ZodVoid, z.ZodObject<{
401
- methods: z.ZodReadonly<z.ZodArray<z.ZodString>>;
402
- probedAt: z.ZodNumber;
403
- }, z.core.$strip>, import("./capability-definition.js").CapabilityMethodKind>;
404
- readonly refreshHardwareDecodeAccels: import("./capability-definition.js").CapabilityMethodSchema<z.ZodVoid, z.ZodObject<{
405
- methods: z.ZodReadonly<z.ZodArray<z.ZodString>>;
406
- probedAt: z.ZodNumber;
407
- }, z.core.$strip>, "mutation">;
408
271
  };
409
272
  };
410
273
  export type IPlatformProbeProvider = InferProvider<typeof platformProbeCapability>;
@@ -1,4 +1,11 @@
1
1
  import type { IScopedLogger } from '../interfaces/logging.js';
2
+ /**
3
+ * Recursively find the first file named exactly `name` under `dir`. Used as the
4
+ * archive-extraction fallback when the declared inner path misses (the archive's
5
+ * top-level dir carries an unpredictable version/arch, e.g. johnvansickle's
6
+ * `ffmpeg-<version>-<arch>-static/`). Returns the absolute path, or `null`.
7
+ */
8
+ export declare function findFileByName(dir: string, name: string): string | null;
2
9
  export interface PlatformInfo {
3
10
  readonly platform: NodeJS.Platform;
4
11
  readonly arch: NodeJS.Architecture;
@@ -618,6 +618,22 @@ export type AppRouter = import("@trpc/server/unstable-core-do-not-import").Route
618
618
  meta: object;
619
619
  }>;
620
620
  }>>;
621
+ clusterNodes: import("@trpc/server").TRPCBuiltRouter<{
622
+ ctx: TrpcContext;
623
+ meta: object;
624
+ errorShape: import("@camstack/types").AugmentedErrorShape;
625
+ transformer: true;
626
+ }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
627
+ forgetNode: import("@trpc/server").TRPCMutationProcedure<{
628
+ input: {
629
+ nodeId: string;
630
+ };
631
+ output: {
632
+ success: boolean;
633
+ };
634
+ meta: object;
635
+ }>;
636
+ }>>;
621
637
  auth: import("@trpc/server").TRPCBuiltRouter<{
622
638
  ctx: TrpcContext;
623
639
  meta: object;
@@ -9649,6 +9665,7 @@ export type AppRouter = import("@trpc/server/unstable-core-do-not-import").Route
9649
9665
  };
9650
9666
  };
9651
9667
  score: number;
9668
+ decodeHwaccel: string | null;
9652
9669
  }[];
9653
9670
  meta: object;
9654
9671
  }>;
@@ -10688,62 +10705,6 @@ export type AppRouter = import("@trpc/server/unstable-core-do-not-import").Route
10688
10705
  };
10689
10706
  meta: object;
10690
10707
  }>;
10691
- getHardwareEncoders: import("@trpc/server").TRPCQueryProcedure<{
10692
- input: {
10693
- nodeId?: string | undefined;
10694
- } | undefined;
10695
- output: {
10696
- encoders: readonly {
10697
- encoder: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
10698
- codec: "H264" | "H265";
10699
- family: "videotoolbox" | "vaapi" | "qsv" | "amf" | "nvenc" | "software";
10700
- available: boolean;
10701
- reason?: string | undefined;
10702
- }[];
10703
- defaultH264: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
10704
- defaultH265: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
10705
- probedAt: number;
10706
- };
10707
- meta: object;
10708
- }>;
10709
- refreshHardwareEncoders: import("@trpc/server").TRPCMutationProcedure<{
10710
- input: {
10711
- nodeId?: string | undefined;
10712
- } | undefined;
10713
- output: {
10714
- encoders: readonly {
10715
- encoder: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
10716
- codec: "H264" | "H265";
10717
- family: "videotoolbox" | "vaapi" | "qsv" | "amf" | "nvenc" | "software";
10718
- available: boolean;
10719
- reason?: string | undefined;
10720
- }[];
10721
- defaultH264: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
10722
- defaultH265: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
10723
- probedAt: number;
10724
- };
10725
- meta: object;
10726
- }>;
10727
- getHardwareDecodeAccels: import("@trpc/server").TRPCQueryProcedure<{
10728
- input: {
10729
- nodeId?: string | undefined;
10730
- } | undefined;
10731
- output: {
10732
- methods: readonly string[];
10733
- probedAt: number;
10734
- };
10735
- meta: object;
10736
- }>;
10737
- refreshHardwareDecodeAccels: import("@trpc/server").TRPCMutationProcedure<{
10738
- input: {
10739
- nodeId?: string | undefined;
10740
- } | undefined;
10741
- output: {
10742
- methods: readonly string[];
10743
- probedAt: number;
10744
- };
10745
- meta: object;
10746
- }>;
10747
10708
  }>>;
10748
10709
  powerMeter: import("@trpc/server").TRPCBuiltRouter<{
10749
10710
  ctx: TrpcContext;
@@ -14995,6 +14956,22 @@ export type AppRouter = import("@trpc/server/unstable-core-do-not-import").Route
14995
14956
  meta: object;
14996
14957
  }>;
14997
14958
  }>>;
14959
+ clusterNodes: import("@trpc/server").TRPCBuiltRouter<{
14960
+ ctx: TrpcContext;
14961
+ meta: object;
14962
+ errorShape: import("@camstack/types").AugmentedErrorShape;
14963
+ transformer: true;
14964
+ }, import("@trpc/server").TRPCDecorateCreateRouterOptions<{
14965
+ forgetNode: import("@trpc/server").TRPCMutationProcedure<{
14966
+ input: {
14967
+ nodeId: string;
14968
+ };
14969
+ output: {
14970
+ success: boolean;
14971
+ };
14972
+ meta: object;
14973
+ }>;
14974
+ }>>;
14998
14975
  auth: import("@trpc/server").TRPCBuiltRouter<{
14999
14976
  ctx: TrpcContext;
15000
14977
  meta: object;
@@ -24026,6 +24003,7 @@ export type AppRouter = import("@trpc/server/unstable-core-do-not-import").Route
24026
24003
  };
24027
24004
  };
24028
24005
  score: number;
24006
+ decodeHwaccel: string | null;
24029
24007
  }[];
24030
24008
  meta: object;
24031
24009
  }>;
@@ -25065,62 +25043,6 @@ export type AppRouter = import("@trpc/server/unstable-core-do-not-import").Route
25065
25043
  };
25066
25044
  meta: object;
25067
25045
  }>;
25068
- getHardwareEncoders: import("@trpc/server").TRPCQueryProcedure<{
25069
- input: {
25070
- nodeId?: string | undefined;
25071
- } | undefined;
25072
- output: {
25073
- encoders: readonly {
25074
- encoder: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
25075
- codec: "H264" | "H265";
25076
- family: "videotoolbox" | "vaapi" | "qsv" | "amf" | "nvenc" | "software";
25077
- available: boolean;
25078
- reason?: string | undefined;
25079
- }[];
25080
- defaultH264: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
25081
- defaultH265: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
25082
- probedAt: number;
25083
- };
25084
- meta: object;
25085
- }>;
25086
- refreshHardwareEncoders: import("@trpc/server").TRPCMutationProcedure<{
25087
- input: {
25088
- nodeId?: string | undefined;
25089
- } | undefined;
25090
- output: {
25091
- encoders: readonly {
25092
- encoder: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
25093
- codec: "H264" | "H265";
25094
- family: "videotoolbox" | "vaapi" | "qsv" | "amf" | "nvenc" | "software";
25095
- available: boolean;
25096
- reason?: string | undefined;
25097
- }[];
25098
- defaultH264: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
25099
- defaultH265: "h264_videotoolbox" | "hevc_videotoolbox" | "h264_vaapi" | "hevc_vaapi" | "h264_nvenc" | "hevc_nvenc" | "h264_qsv" | "hevc_qsv" | "h264_amf" | "hevc_amf" | "libx264" | "libx265";
25100
- probedAt: number;
25101
- };
25102
- meta: object;
25103
- }>;
25104
- getHardwareDecodeAccels: import("@trpc/server").TRPCQueryProcedure<{
25105
- input: {
25106
- nodeId?: string | undefined;
25107
- } | undefined;
25108
- output: {
25109
- methods: readonly string[];
25110
- probedAt: number;
25111
- };
25112
- meta: object;
25113
- }>;
25114
- refreshHardwareDecodeAccels: import("@trpc/server").TRPCMutationProcedure<{
25115
- input: {
25116
- nodeId?: string | undefined;
25117
- } | undefined;
25118
- output: {
25119
- methods: readonly string[];
25120
- probedAt: number;
25121
- };
25122
- meta: object;
25123
- }>;
25124
25046
  }>>;
25125
25047
  powerMeter: import("@trpc/server").TRPCBuiltRouter<{
25126
25048
  ctx: TrpcContext;
@@ -6,7 +6,7 @@
6
6
  * scope+access check inside `protectedProcedure` (see
7
7
  * `server/backend/src/api/trpc/trpc.middleware.ts`).
8
8
  *
9
- * Coverage: 737 method paths across 111 capabilities.
9
+ * Coverage: 733 method paths across 111 capabilities.
10
10
  */
11
11
  import type { CapabilityMethodAccess } from '../capabilities/capability-definition.js';
12
12
  export interface MethodAccessRecord {
package/dist/index.js CHANGED
@@ -16995,7 +16995,10 @@ var AgentLoadSummarySchema = zod.z.object({
16995
16995
  online: zod.z.boolean(),
16996
16996
  load: RunnerLocalLoadSchema,
16997
16997
  /** Computed score used by the L2 capacity balancer (lower = less loaded). */
16998
- score: zod.z.number()
16998
+ score: zod.z.number(),
16999
+ /** This node's decode hwaccel backend (per-node `probedBestHwaccel`), or null
17000
+ * when not yet probed — for the cluster Pipeline table UI (P0.2). */
17001
+ decodeHwaccel: zod.z.string().nullable()
16999
17002
  });
17000
17003
  /**
17001
17004
  * Aggregate metrics across the whole detection cluster. Replaces the legacy
@@ -20845,21 +20848,13 @@ var HardwareEncoderProbeSchema = zod.z.object({
20845
20848
  available: zod.z.boolean(),
20846
20849
  reason: zod.z.string().optional()
20847
20850
  });
20848
- var HardwareEncodersSchema = zod.z.object({
20851
+ zod.z.object({
20849
20852
  encoders: zod.z.array(HardwareEncoderProbeSchema).readonly(),
20850
20853
  defaultH264: HardwareEncoderIdSchema,
20851
20854
  defaultH265: HardwareEncoderIdSchema,
20852
20855
  probedAt: zod.z.number()
20853
20856
  });
20854
- /**
20855
- * Decode-side companion to {@link HardwareEncodersSchema}: the `-hwaccel`
20856
- * methods the configured ffmpeg binary actually supports (parsed from
20857
- * `ffmpeg -hwaccels`). Used to gate decode-hwaccel attempts so the transcode
20858
- * egress never spends a spawn on a backend this build cannot offer. Per-stream
20859
- * decode fragility (e.g. VideoToolbox HEVC) is still handled by the egress's
20860
- * software fallback — this only filters out wholly-unsupported backends.
20861
- */
20862
- var HardwareDecodeAccelsSchema = zod.z.object({
20857
+ zod.z.object({
20863
20858
  methods: zod.z.array(zod.z.string()).readonly(),
20864
20859
  probedAt: zod.z.number()
20865
20860
  });
@@ -20930,24 +20925,7 @@ var platformProbeCapability = {
20930
20925
  getCapabilities: require_sleep.method(zod.z.void(), PlatformCapabilitiesSchema),
20931
20926
  getHardware: require_sleep.method(zod.z.void(), HardwareInfoSchema),
20932
20927
  resolveInferenceConfig: require_sleep.method(zod.z.object({ requirements: zod.z.array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema),
20933
- resolveHwAccel: require_sleep.method(zod.z.object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema),
20934
- /**
20935
- * Hardware-encoder probe — see Task #185. Cached after first call.
20936
- */
20937
- getHardwareEncoders: require_sleep.method(zod.z.void(), HardwareEncodersSchema),
20938
- refreshHardwareEncoders: require_sleep.method(zod.z.void(), HardwareEncodersSchema, {
20939
- kind: "mutation",
20940
- auth: "admin"
20941
- }),
20942
- /**
20943
- * Decode-side hw-accel probe — the `-hwaccel` methods the configured ffmpeg
20944
- * binary supports (via `ffmpeg -hwaccels`). Cached after first call.
20945
- */
20946
- getHardwareDecodeAccels: require_sleep.method(zod.z.void(), HardwareDecodeAccelsSchema),
20947
- refreshHardwareDecodeAccels: require_sleep.method(zod.z.void(), HardwareDecodeAccelsSchema, {
20948
- kind: "mutation",
20949
- auth: "admin"
20950
- })
20928
+ resolveHwAccel: require_sleep.method(zod.z.object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema)
20951
20929
  }
20952
20930
  };
20953
20931
  //#endregion
@@ -25967,30 +25945,6 @@ var METHOD_ACCESS_MAP = Object.freeze({
25967
25945
  addonId: null,
25968
25946
  access: "view"
25969
25947
  },
25970
- "platformProbe.getHardwareDecodeAccels": {
25971
- capName: "platform-probe",
25972
- capScope: "system",
25973
- addonId: null,
25974
- access: "view"
25975
- },
25976
- "platformProbe.getHardwareEncoders": {
25977
- capName: "platform-probe",
25978
- capScope: "system",
25979
- addonId: null,
25980
- access: "view"
25981
- },
25982
- "platformProbe.refreshHardwareDecodeAccels": {
25983
- capName: "platform-probe",
25984
- capScope: "system",
25985
- addonId: null,
25986
- access: "create"
25987
- },
25988
- "platformProbe.refreshHardwareEncoders": {
25989
- capName: "platform-probe",
25990
- capScope: "system",
25991
- addonId: null,
25992
- access: "create"
25993
- },
25994
25948
  "platformProbe.resolveHwAccel": {
25995
25949
  capName: "platform-probe",
25996
25950
  capScope: "system",
package/dist/index.mjs CHANGED
@@ -16994,7 +16994,10 @@ var AgentLoadSummarySchema = z.object({
16994
16994
  online: z.boolean(),
16995
16995
  load: RunnerLocalLoadSchema,
16996
16996
  /** Computed score used by the L2 capacity balancer (lower = less loaded). */
16997
- score: z.number()
16997
+ score: z.number(),
16998
+ /** This node's decode hwaccel backend (per-node `probedBestHwaccel`), or null
16999
+ * when not yet probed — for the cluster Pipeline table UI (P0.2). */
17000
+ decodeHwaccel: z.string().nullable()
16998
17001
  });
16999
17002
  /**
17000
17003
  * Aggregate metrics across the whole detection cluster. Replaces the legacy
@@ -20844,21 +20847,13 @@ var HardwareEncoderProbeSchema = z.object({
20844
20847
  available: z.boolean(),
20845
20848
  reason: z.string().optional()
20846
20849
  });
20847
- var HardwareEncodersSchema = z.object({
20850
+ z.object({
20848
20851
  encoders: z.array(HardwareEncoderProbeSchema).readonly(),
20849
20852
  defaultH264: HardwareEncoderIdSchema,
20850
20853
  defaultH265: HardwareEncoderIdSchema,
20851
20854
  probedAt: z.number()
20852
20855
  });
20853
- /**
20854
- * Decode-side companion to {@link HardwareEncodersSchema}: the `-hwaccel`
20855
- * methods the configured ffmpeg binary actually supports (parsed from
20856
- * `ffmpeg -hwaccels`). Used to gate decode-hwaccel attempts so the transcode
20857
- * egress never spends a spawn on a backend this build cannot offer. Per-stream
20858
- * decode fragility (e.g. VideoToolbox HEVC) is still handled by the egress's
20859
- * software fallback — this only filters out wholly-unsupported backends.
20860
- */
20861
- var HardwareDecodeAccelsSchema = z.object({
20856
+ z.object({
20862
20857
  methods: z.array(z.string()).readonly(),
20863
20858
  probedAt: z.number()
20864
20859
  });
@@ -20929,24 +20924,7 @@ var platformProbeCapability = {
20929
20924
  getCapabilities: method(z.void(), PlatformCapabilitiesSchema),
20930
20925
  getHardware: method(z.void(), HardwareInfoSchema),
20931
20926
  resolveInferenceConfig: method(z.object({ requirements: z.array(ModelRequirementSchema).readonly() }), ResolvedInferenceConfigSchema),
20932
- resolveHwAccel: method(z.object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema),
20933
- /**
20934
- * Hardware-encoder probe — see Task #185. Cached after first call.
20935
- */
20936
- getHardwareEncoders: method(z.void(), HardwareEncodersSchema),
20937
- refreshHardwareEncoders: method(z.void(), HardwareEncodersSchema, {
20938
- kind: "mutation",
20939
- auth: "admin"
20940
- }),
20941
- /**
20942
- * Decode-side hw-accel probe — the `-hwaccel` methods the configured ffmpeg
20943
- * binary supports (via `ffmpeg -hwaccels`). Cached after first call.
20944
- */
20945
- getHardwareDecodeAccels: method(z.void(), HardwareDecodeAccelsSchema),
20946
- refreshHardwareDecodeAccels: method(z.void(), HardwareDecodeAccelsSchema, {
20947
- kind: "mutation",
20948
- auth: "admin"
20949
- })
20927
+ resolveHwAccel: method(z.object({ prefer: HwAccelBackendInputSchema }), HwAccelResolutionSchema)
20950
20928
  }
20951
20929
  };
20952
20930
  //#endregion
@@ -25966,30 +25944,6 @@ var METHOD_ACCESS_MAP = Object.freeze({
25966
25944
  addonId: null,
25967
25945
  access: "view"
25968
25946
  },
25969
- "platformProbe.getHardwareDecodeAccels": {
25970
- capName: "platform-probe",
25971
- capScope: "system",
25972
- addonId: null,
25973
- access: "view"
25974
- },
25975
- "platformProbe.getHardwareEncoders": {
25976
- capName: "platform-probe",
25977
- capScope: "system",
25978
- addonId: null,
25979
- access: "view"
25980
- },
25981
- "platformProbe.refreshHardwareDecodeAccels": {
25982
- capName: "platform-probe",
25983
- capScope: "system",
25984
- addonId: null,
25985
- access: "create"
25986
- },
25987
- "platformProbe.refreshHardwareEncoders": {
25988
- capName: "platform-probe",
25989
- capScope: "system",
25990
- addonId: null,
25991
- access: "create"
25992
- },
25993
25947
  "platformProbe.resolveHwAccel": {
25994
25948
  capName: "platform-probe",
25995
25949
  capScope: "system",
@@ -266,6 +266,15 @@ export interface IKernelServices {
266
266
  * (`resolveHwAccel`), not a bespoke Moleculer service.
267
267
  */
268
268
  readonly hwaccel?: IKernelHwAccel;
269
+ /**
270
+ * Kernel inference-runtime hardware resolver — the node's own inference
271
+ * accelerators (gpu/npu), probed LOCALLY in-process. The exact model as
272
+ * {@link hwaccel}: every node (hub + forked worker + remote agent) resolves
273
+ * its OWN hardware, NEVER the `platform-probe` singleton (which returns the
274
+ * hub's hardware to a forked agent child). The detection-pipeline maps this to
275
+ * a runtime via the shared `scoreRuntimes` / `pickBestRuntime`.
276
+ */
277
+ readonly inferenceEngine?: IKernelInferenceEngine;
269
278
  /**
270
279
  * Capability registry — provider lookups, native-cap resolution, wrapper listing.
271
280
  * Hub-only: forked workers don't see this (they use `ctx.api` for cross-process calls).
@@ -343,6 +352,24 @@ export interface IKernelHwAccel {
343
352
  */
344
353
  readonly resolve: (prefer?: HwAccelBackend | 'none' | null) => Promise<HwAccelResolution>;
345
354
  }
355
+ /** THIS node's inference accelerators (gpu/npu), probed locally in-process. */
356
+ export interface KernelInferenceHardware {
357
+ readonly gpu: {
358
+ readonly type: string;
359
+ } | null;
360
+ readonly npu: {
361
+ readonly type: string;
362
+ } | null;
363
+ }
364
+ export interface IKernelInferenceEngine {
365
+ /**
366
+ * Probe the LOCAL host and return its inference accelerators. Deterministic
367
+ * per host — safe to call repeatedly. The exact model as {@link IKernelHwAccel}:
368
+ * every node resolves its OWN hardware, so the detection-pipeline never adopts
369
+ * a remote node's runtime from the `platform-probe` singleton.
370
+ */
371
+ readonly resolveHardware: () => Promise<KernelInferenceHardware>;
372
+ }
346
373
  export interface IKernelStreamProbe {
347
374
  /**
348
375
  * Run ffprobe on an RTSP / HTTP stream URL and return the raw
@@ -54,6 +54,15 @@ export interface AgentLoadSummary {
54
54
  readonly load: RunnerLocalLoad;
55
55
  /** Computed score used by the L2 capacity balancer (lower = less loaded). */
56
56
  readonly score: number;
57
+ /**
58
+ * The decode hwaccel backend this node runs on (e.g. `videotoolbox`, `vaapi`,
59
+ * `qsv`), from the decoder addon's per-node `probedBestHwaccel@<node>` setting,
60
+ * or `null` when not yet probed. For the cluster Pipeline table UI's per-node
61
+ * capability column (P0.2). Sourced from a node-LOCAL probe published to a
62
+ * per-node setting — never the `platform-probe` singleton (whose per-node pin
63
+ * answers with the hub's hardware).
64
+ */
65
+ readonly decodeHwaccel: string | null;
57
66
  }
58
67
  /**
59
68
  * Aggregate metrics across the whole detection cluster.
package/dist/node.js CHANGED
@@ -31,6 +31,24 @@ let node_stream = require("node:stream");
31
31
  let node_child_process = require("node:child_process");
32
32
  let node_crypto = require("node:crypto");
33
33
  //#region src/deps/binary-downloader.ts
34
+ /**
35
+ * Recursively find the first file named exactly `name` under `dir`. Used as the
36
+ * archive-extraction fallback when the declared inner path misses (the archive's
37
+ * top-level dir carries an unpredictable version/arch, e.g. johnvansickle's
38
+ * `ffmpeg-<version>-<arch>-static/`). Returns the absolute path, or `null`.
39
+ */
40
+ function findFileByName(dir, name) {
41
+ try {
42
+ for (const entry of (0, node_fs.readdirSync)(dir, { withFileTypes: true })) {
43
+ const full = (0, node_path.join)(dir, entry.name);
44
+ if (entry.isDirectory()) {
45
+ const nested = findFileByName(full, name);
46
+ if (nested !== null) return nested;
47
+ } else if (entry.isFile() && entry.name === name) return full;
48
+ }
49
+ } catch {}
50
+ return null;
51
+ }
34
52
  function getPlatformInfo() {
35
53
  return {
36
54
  platform: process.platform,
@@ -109,8 +127,12 @@ async function downloadBinary(opts) {
109
127
  ], { stdio: "pipe" });
110
128
  if (archiveInnerPath) {
111
129
  const { copyFileSync } = await import("node:fs");
112
- const sourcePath = (0, node_path.join)(tmpExtractDir, archiveInnerPath);
113
- if (!(0, node_fs.existsSync)(sourcePath)) throw new Error(`Binary not found in archive at ${archiveInnerPath}`);
130
+ let sourcePath = (0, node_path.join)(tmpExtractDir, archiveInnerPath);
131
+ if (!(0, node_fs.existsSync)(sourcePath)) {
132
+ const found = findFileByName(tmpExtractDir, name);
133
+ if (found === null) throw new Error(`Binary "${name}" not found in archive (tried inner path "${archiveInnerPath}" and a recursive search)`);
134
+ sourcePath = found;
135
+ }
114
136
  copyFileSync(sourcePath, targetPath);
115
137
  }
116
138
  (0, node_fs.unlinkSync)(tmpArchive);
package/dist/node.mjs CHANGED
@@ -8,6 +8,24 @@ import { Readable } from "node:stream";
8
8
  import { execFileSync } from "node:child_process";
9
9
  import { createHash } from "node:crypto";
10
10
  //#region src/deps/binary-downloader.ts
11
+ /**
12
+ * Recursively find the first file named exactly `name` under `dir`. Used as the
13
+ * archive-extraction fallback when the declared inner path misses (the archive's
14
+ * top-level dir carries an unpredictable version/arch, e.g. johnvansickle's
15
+ * `ffmpeg-<version>-<arch>-static/`). Returns the absolute path, or `null`.
16
+ */
17
+ function findFileByName(dir, name) {
18
+ try {
19
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
20
+ const full = join(dir, entry.name);
21
+ if (entry.isDirectory()) {
22
+ const nested = findFileByName(full, name);
23
+ if (nested !== null) return nested;
24
+ } else if (entry.isFile() && entry.name === name) return full;
25
+ }
26
+ } catch {}
27
+ return null;
28
+ }
11
29
  function getPlatformInfo() {
12
30
  return {
13
31
  platform: process.platform,
@@ -86,8 +104,12 @@ async function downloadBinary(opts) {
86
104
  ], { stdio: "pipe" });
87
105
  if (archiveInnerPath) {
88
106
  const { copyFileSync } = await import("node:fs");
89
- const sourcePath = join(tmpExtractDir, archiveInnerPath);
90
- if (!existsSync(sourcePath)) throw new Error(`Binary not found in archive at ${archiveInnerPath}`);
107
+ let sourcePath = join(tmpExtractDir, archiveInnerPath);
108
+ if (!existsSync(sourcePath)) {
109
+ const found = findFileByName(tmpExtractDir, name);
110
+ if (found === null) throw new Error(`Binary "${name}" not found in archive (tried inner path "${archiveInnerPath}" and a recursive search)`);
111
+ sourcePath = found;
112
+ }
91
113
  copyFileSync(sourcePath, targetPath);
92
114
  }
93
115
  unlinkSync(tmpArchive);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/types",
3
- "version": "1.1.22",
3
+ "version": "1.1.24",
4
4
  "description": "Shared types, interfaces, and model catalogs for the CamStack detection ecosystem",
5
5
  "keywords": [
6
6
  "camstack",