@camstack/addon-pipeline-orchestrator 1.1.25 → 1.1.26

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.
@@ -18,7 +18,7 @@ var e = {
18
18
  },
19
19
  "@camstack/types": {
20
20
  name: "@camstack/types",
21
- version: "1.1.27",
21
+ version: "1.1.28",
22
22
  scope: ["default"],
23
23
  loaded: !1,
24
24
  from: "addon_pipeline_orchestrator_widgets",
@@ -36,7 +36,7 @@ async function r() {
36
36
  }
37
37
  },
38
38
  "@camstack/types": {
39
- version: "1.1.27",
39
+ version: "1.1.28",
40
40
  scope: "default",
41
41
  shareConfig: {
42
42
  singleton: !0,
package/dist/index.js CHANGED
@@ -7739,6 +7739,36 @@ var EncodeProfileSchema = object({
7739
7739
  */
7740
7740
  outputArgs: array(string()).optional()
7741
7741
  });
7742
+ /**
7743
+ * Per-call node pinning for `ctx.api` capability calls.
7744
+ *
7745
+ * A capability call normally resolves to its DEFAULT provider — a `singleton`
7746
+ * cap resolves to the hub, a device-scoped cap to the device's owning node. To
7747
+ * query a SPECIFIC node's provider instead (e.g. a remote agent's own
7748
+ * in-process `platform-probe` hardware, which the hub cannot probe), pin the
7749
+ * call to that node.
7750
+ *
7751
+ * The nodeId rides OUT-OF-BAND in the tRPC call context (NOT in the validated
7752
+ * method args), so capability method signatures stay `nodeId`-free — node
7753
+ * targeting is a property of the CALL, not of the method. The transport lifts
7754
+ * it from `op.context` onto the `CapCallInput.nodeId` field (`ipcParentLink`),
7755
+ * and the hub parent's `onUnownedCall` passes it to the `CapRouteResolver`,
7756
+ * which classifies a pinned agent node as `agent-child-forward`
7757
+ * (`$agent-cap-fwd.forward` → the agent's in-process provider).
7758
+ *
7759
+ * Usage at a call site:
7760
+ *
7761
+ * await api.platformProbe.getCapabilities.query(undefined, nodePin(nodeId))
7762
+ */
7763
+ /** tRPC `op.context` key carrying a per-call node pin. */
7764
+ var CAP_NODE_PIN_CONTEXT_KEY = "__camstackNodePin";
7765
+ /**
7766
+ * Build the tRPC request options that pin a single capability call to `nodeId`.
7767
+ * Pass as the second argument to `.query(input, …)` / `.mutate(input, …)`.
7768
+ */
7769
+ function nodePin(nodeId) {
7770
+ return { context: { [CAP_NODE_PIN_CONTEXT_KEY]: nodeId } };
7771
+ }
7742
7772
  var YAMNET_TO_MACRO = {
7743
7773
  mapping: {
7744
7774
  Speech: "speech",
@@ -13789,7 +13819,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
13789
13819
  id: string(),
13790
13820
  name: string(),
13791
13821
  isPullMode: boolean().optional(),
13792
- priority: number().optional()
13822
+ priority: number().optional(),
13823
+ hwaccel: string().optional(),
13824
+ probedBestHwaccel: string().optional()
13793
13825
  })), method(DecoderSessionConfigSchema, object({
13794
13826
  sessionId: string(),
13795
13827
  nodeId: string()
@@ -26346,22 +26378,19 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
26346
26378
  }));
26347
26379
  }
26348
26380
  /**
26349
- * Read a node's `probedBestHwaccel` from the decoder-ffmpeg addon's per-node
26350
- * settings via the hub-routed `addonSettings` cap. Returns `null` when the
26351
- * value is empty/unset, `undefined` on a read failure (keep the last known).
26352
- * Mirrors {@link readDetectionPipelineEngine}.
26381
+ * Read a node's `probedBestHwaccel` from whatever decoder backend is ACTIVE
26382
+ * on that node — via the `decoder` cap (`getInfo`, nodePin), NOT an addon-id
26383
+ * lookup. Works for any backend (ffmpeg / node-av / future) and no longer
26384
+ * returns empty on a node-av-only node (the old `decoder-ffmpeg`-keyed read
26385
+ * did). Returns `null` when the value is empty/unset, `undefined` on a read
26386
+ * failure (keep the last known). Mirrors {@link readDetectionPipelineEngine}.
26353
26387
  */
26354
26388
  async readNodeDecodeHwaccel(nodeId) {
26355
- const api = this.ctx.api;
26356
- if (!api?.addonSettings) return void 0;
26357
26389
  try {
26358
- const schema = await api.addonSettings.getGlobalSettings.query({
26359
- addonId: "decoder-ffmpeg",
26360
- nodeId
26361
- });
26362
- if (!schema) return void 0;
26363
- for (const s of schema.sections) for (const f of s.fields) if (f.key === "probedBestHwaccel") return typeof f.value === "string" && f.value.length > 0 ? f.value : null;
26364
- return null;
26390
+ const info = await this.ctx.api.decoder.getInfo.query(void 0, nodePin(nodeId));
26391
+ if (!info) return void 0;
26392
+ const probed = info.probedBestHwaccel;
26393
+ return typeof probed === "string" && probed.length > 0 ? probed : null;
26365
26394
  } catch {
26366
26395
  return;
26367
26396
  }
@@ -28144,6 +28173,26 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
28144
28173
  }
28145
28174
  ]
28146
28175
  },
28176
+ {
28177
+ id: "decoder",
28178
+ title: "Decoder Backend",
28179
+ tab: "pipeline",
28180
+ fields: [{
28181
+ key: "backend",
28182
+ type: "select",
28183
+ label: "Decoder Backend",
28184
+ default: "nodeav",
28185
+ immediate: true,
28186
+ perNode: true,
28187
+ options: [{
28188
+ value: "nodeav",
28189
+ label: "node-av (in-process)"
28190
+ }, {
28191
+ value: "ffmpeg",
28192
+ label: "ffmpeg (subprocess)"
28193
+ }]
28194
+ }]
28195
+ },
28147
28196
  {
28148
28197
  id: "load",
28149
28198
  title: "Load Balancer",
package/dist/index.mjs CHANGED
@@ -7735,6 +7735,36 @@ var EncodeProfileSchema = object({
7735
7735
  */
7736
7736
  outputArgs: array(string()).optional()
7737
7737
  });
7738
+ /**
7739
+ * Per-call node pinning for `ctx.api` capability calls.
7740
+ *
7741
+ * A capability call normally resolves to its DEFAULT provider — a `singleton`
7742
+ * cap resolves to the hub, a device-scoped cap to the device's owning node. To
7743
+ * query a SPECIFIC node's provider instead (e.g. a remote agent's own
7744
+ * in-process `platform-probe` hardware, which the hub cannot probe), pin the
7745
+ * call to that node.
7746
+ *
7747
+ * The nodeId rides OUT-OF-BAND in the tRPC call context (NOT in the validated
7748
+ * method args), so capability method signatures stay `nodeId`-free — node
7749
+ * targeting is a property of the CALL, not of the method. The transport lifts
7750
+ * it from `op.context` onto the `CapCallInput.nodeId` field (`ipcParentLink`),
7751
+ * and the hub parent's `onUnownedCall` passes it to the `CapRouteResolver`,
7752
+ * which classifies a pinned agent node as `agent-child-forward`
7753
+ * (`$agent-cap-fwd.forward` → the agent's in-process provider).
7754
+ *
7755
+ * Usage at a call site:
7756
+ *
7757
+ * await api.platformProbe.getCapabilities.query(undefined, nodePin(nodeId))
7758
+ */
7759
+ /** tRPC `op.context` key carrying a per-call node pin. */
7760
+ var CAP_NODE_PIN_CONTEXT_KEY = "__camstackNodePin";
7761
+ /**
7762
+ * Build the tRPC request options that pin a single capability call to `nodeId`.
7763
+ * Pass as the second argument to `.query(input, …)` / `.mutate(input, …)`.
7764
+ */
7765
+ function nodePin(nodeId) {
7766
+ return { context: { [CAP_NODE_PIN_CONTEXT_KEY]: nodeId } };
7767
+ }
7738
7768
  var YAMNET_TO_MACRO = {
7739
7769
  mapping: {
7740
7770
  Speech: "speech",
@@ -13785,7 +13815,9 @@ method(object({ codec: string() }), boolean()), method(_void(), object({
13785
13815
  id: string(),
13786
13816
  name: string(),
13787
13817
  isPullMode: boolean().optional(),
13788
- priority: number().optional()
13818
+ priority: number().optional(),
13819
+ hwaccel: string().optional(),
13820
+ probedBestHwaccel: string().optional()
13789
13821
  })), method(DecoderSessionConfigSchema, object({
13790
13822
  sessionId: string(),
13791
13823
  nodeId: string()
@@ -26342,22 +26374,19 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
26342
26374
  }));
26343
26375
  }
26344
26376
  /**
26345
- * Read a node's `probedBestHwaccel` from the decoder-ffmpeg addon's per-node
26346
- * settings via the hub-routed `addonSettings` cap. Returns `null` when the
26347
- * value is empty/unset, `undefined` on a read failure (keep the last known).
26348
- * Mirrors {@link readDetectionPipelineEngine}.
26377
+ * Read a node's `probedBestHwaccel` from whatever decoder backend is ACTIVE
26378
+ * on that node — via the `decoder` cap (`getInfo`, nodePin), NOT an addon-id
26379
+ * lookup. Works for any backend (ffmpeg / node-av / future) and no longer
26380
+ * returns empty on a node-av-only node (the old `decoder-ffmpeg`-keyed read
26381
+ * did). Returns `null` when the value is empty/unset, `undefined` on a read
26382
+ * failure (keep the last known). Mirrors {@link readDetectionPipelineEngine}.
26349
26383
  */
26350
26384
  async readNodeDecodeHwaccel(nodeId) {
26351
- const api = this.ctx.api;
26352
- if (!api?.addonSettings) return void 0;
26353
26385
  try {
26354
- const schema = await api.addonSettings.getGlobalSettings.query({
26355
- addonId: "decoder-ffmpeg",
26356
- nodeId
26357
- });
26358
- if (!schema) return void 0;
26359
- for (const s of schema.sections) for (const f of s.fields) if (f.key === "probedBestHwaccel") return typeof f.value === "string" && f.value.length > 0 ? f.value : null;
26360
- return null;
26386
+ const info = await this.ctx.api.decoder.getInfo.query(void 0, nodePin(nodeId));
26387
+ if (!info) return void 0;
26388
+ const probed = info.probedBestHwaccel;
26389
+ return typeof probed === "string" && probed.length > 0 ? probed : null;
26361
26390
  } catch {
26362
26391
  return;
26363
26392
  }
@@ -28140,6 +28169,26 @@ var PipelineOrchestratorAddon = class PipelineOrchestratorAddon extends BaseAddo
28140
28169
  }
28141
28170
  ]
28142
28171
  },
28172
+ {
28173
+ id: "decoder",
28174
+ title: "Decoder Backend",
28175
+ tab: "pipeline",
28176
+ fields: [{
28177
+ key: "backend",
28178
+ type: "select",
28179
+ label: "Decoder Backend",
28180
+ default: "nodeav",
28181
+ immediate: true,
28182
+ perNode: true,
28183
+ options: [{
28184
+ value: "nodeav",
28185
+ label: "node-av (in-process)"
28186
+ }, {
28187
+ value: "ffmpeg",
28188
+ label: "ffmpeg (subprocess)"
28189
+ }]
28190
+ }]
28191
+ },
28143
28192
  {
28144
28193
  id: "load",
28145
28194
  title: "Load Balancer",
@@ -30,7 +30,7 @@ async function d(e) {
30
30
  }
31
31
  }
32
32
  async function f() {
33
- return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-BjQq9CHk.mjs")).catch((e) => {
33
+ return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-0vYngRZJ.mjs")).catch((e) => {
34
34
  throw l = void 0, e;
35
35
  }), l;
36
36
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@camstack/addon-pipeline-orchestrator",
3
- "version": "1.1.25",
3
+ "version": "1.1.26",
4
4
  "description": "Hub-side camera-to-agent load balancer — tracks runner capacity and dispatches attachCamera calls to the optimal pipeline-runner instance",
5
5
  "keywords": [
6
6
  "camstack",